whitespace police:
[gpgme.git] / lang / python / src / core.py
1 # -*- coding: utf-8 -*-
2
3 from __future__ import absolute_import, print_function, unicode_literals
4 del absolute_import, print_function, unicode_literals
5
6 import re
7 import os
8 import warnings
9 import weakref
10
11 from . import gpgme
12 from .errors import errorcheck, GPGMEError
13 from . import constants
14 from . import errors
15 from . import util
16
17 # Copyright (C) 2016-2017 g10 Code GmbH
18 # Copyright (C) 2004,2008 Igor Belyi <belyi@users.sourceforge.net>
19 # Copyright (C) 2002 John Goerzen <jgoerzen@complete.org>
20 #
21 #    This library is free software; you can redistribute it and/or
22 #    modify it under the terms of the GNU Lesser General Public
23 #    License as published by the Free Software Foundation; either
24 #    version 2.1 of the License, or (at your option) any later version.
25 #
26 #    This library is distributed in the hope that it will be useful,
27 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
28 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
29 #    Lesser General Public License for more details.
30 #
31 #    You should have received a copy of the GNU Lesser General Public
32 #    License along with this library; if not, write to the Free Software
33 #    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
34
35 """Core functionality
36
37 Core functionality of GPGME wrapped in a object-oriented fashion.
38 Provides the 'Context' class for performing cryptographic operations,
39 and the 'Data' class describing buffers of data.
40
41 """
42
43
44 class GpgmeWrapper(object):
45     """Base wrapper class
46
47     Not to be instantiated directly.
48
49     """
50
51     def __init__(self, wrapped):
52         self._callback_excinfo = None
53         self.wrapped = wrapped
54
55     def __repr__(self):
56         return '<{}/{!r}>'.format(super(GpgmeWrapper, self).__repr__(),
57                                   self.wrapped)
58
59     def __str__(self):
60         acc = ['{}.{}'.format(__name__, self.__class__.__name__)]
61         flags = [f for f in self._boolean_properties if getattr(self, f)]
62         if flags:
63             acc.append('({})'.format(' '.join(flags)))
64
65         return '<{}>'.format(' '.join(acc))
66
67     def __hash__(self):
68         return hash(repr(self.wrapped))
69
70     def __eq__(self, other):
71         if other is None:
72             return False
73         else:
74             return repr(self.wrapped) == repr(other.wrapped)
75
76     @property
77     def _ctype(self):
78         """The name of the c type wrapped by this class
79
80         Must be set by child classes.
81
82         """
83         raise NotImplementedError()
84
85     @property
86     def _cprefix(self):
87         """The common prefix of c functions wrapped by this class
88
89         Must be set by child classes.
90
91         """
92         raise NotImplementedError()
93
94     def _errorcheck(self, name):
95         """Must be implemented by child classes.
96
97         This function must return a trueish value for all c functions
98         returning gpgme_error_t."""
99         raise NotImplementedError()
100
101     """The set of all boolean properties"""
102     _boolean_properties = set()
103
104     def __wrap_boolean_property(self, key, do_set=False, value=None):
105         get_func = getattr(gpgme,
106                            "{}get_{}".format(self._cprefix, key))
107         set_func = getattr(gpgme,
108                            "{}set_{}".format(self._cprefix, key))
109
110         def get(slf):
111             return bool(get_func(slf.wrapped))
112
113         def set_(slf, value):
114             set_func(slf.wrapped, bool(value))
115
116         p = property(get, set_, doc="{} flag".format(key))
117         setattr(self.__class__, key, p)
118
119         if do_set:
120             set_(self, bool(value))
121         else:
122             return get(self)
123
124     _munge_docstring = re.compile(r'gpgme_([^(]*)\(([^,]*), (.*\) -> .*)')
125
126     def __getattr__(self, key):
127         """On-the-fly generation of wrapper methods and properties"""
128         if key[0] == '_' or self._cprefix is None:
129             return None
130
131         if key in self._boolean_properties:
132             return self.__wrap_boolean_property(key)
133
134         name = self._cprefix + key
135         func = getattr(gpgme, name)
136
137         if self._errorcheck(name):
138             def _funcwrap(slf, *args):
139                 result = func(slf.wrapped, *args)
140                 if slf._callback_excinfo:
141                     gpgme.gpg_raise_callback_exception(slf)
142                 return errorcheck(result, name)
143         else:
144             def _funcwrap(slf, *args):
145                 result = func(slf.wrapped, *args)
146                 if slf._callback_excinfo:
147                     gpgme.gpg_raise_callback_exception(slf)
148                 return result
149
150         doc = self._munge_docstring.sub(r'\2.\1(\3', getattr(func, "__doc__"))
151         _funcwrap.__doc__ = doc
152
153         # Monkey-patch the class.
154         setattr(self.__class__, key, _funcwrap)
155
156         # Bind the method to 'self'.
157         def wrapper(*args):
158             return _funcwrap(self, *args)
159         wrapper.__doc__ = doc
160
161         return wrapper
162
163     def __setattr__(self, key, value):
164         """On-the-fly generation of properties"""
165         if key in self._boolean_properties:
166             self.__wrap_boolean_property(key, True, value)
167         else:
168             super(GpgmeWrapper, self).__setattr__(key, value)
169
170
171 class Context(GpgmeWrapper):
172     """Context for cryptographic operations
173
174     All cryptographic operations in GPGME are performed within a
175     context, which contains the internal state of the operation as
176     well as configuration parameters.  By using several contexts you
177     can run several cryptographic operations in parallel, with
178     different configuration.
179
180     Access to a context must be synchronized.
181
182     """
183
184     def __init__(self, armor=False, textmode=False, offline=False,
185                  signers=[], pinentry_mode=constants.PINENTRY_MODE_DEFAULT,
186                  protocol=constants.PROTOCOL_OpenPGP,
187                  wrapped=None, home_dir=None):
188         """Construct a context object
189
190         Keyword arguments:
191         armor           -- enable ASCII armoring (default False)
192         textmode        -- enable canonical text mode (default False)
193         offline         -- do not contact external key sources (default False)
194         signers         -- list of keys used for signing (default [])
195         pinentry_mode   -- pinentry mode (default PINENTRY_MODE_DEFAULT)
196         protocol        -- protocol to use (default PROTOCOL_OpenPGP)
197         home_dir        -- state directory (default is the engine default)
198
199         """
200         if wrapped:
201             self.own = False
202         else:
203             tmp = gpgme.new_gpgme_ctx_t_p()
204             errorcheck(gpgme.gpgme_new(tmp))
205             wrapped = gpgme.gpgme_ctx_t_p_value(tmp)
206             gpgme.delete_gpgme_ctx_t_p(tmp)
207             self.own = True
208         super(Context, self).__init__(wrapped)
209         self.armor = armor
210         self.textmode = textmode
211         self.offline = offline
212         self.signers = signers
213         self.pinentry_mode = pinentry_mode
214         self.protocol = protocol
215         self.home_dir = home_dir
216
217     def __read__(self, sink, data):
218         """Read helper
219
220         Helper function to retrieve the results of an operation, or
221         None if SINK is given.
222         """
223         if sink or data is None:
224             return None
225         data.seek(0, os.SEEK_SET)
226         return data.read()
227
228     def __repr__(self):
229         return (
230             "Context(armor={0.armor}, "
231             "textmode={0.textmode}, offline={0.offline}, "
232             "signers={0.signers}, pinentry_mode={0.pinentry_mode}, "
233             "protocol={0.protocol}, home_dir={0.home_dir}"
234             ")").format(self)
235
236     def encrypt(self, plaintext, recipients=[], sign=True, sink=None,
237                 passphrase=None, always_trust=False, add_encrypt_to=False,
238                 prepare=False, expect_sign=False, compress=True):
239         """Encrypt data
240
241         Encrypt the given plaintext for the given recipients.  If the
242         list of recipients is empty, the data is encrypted
243         symmetrically with a passphrase.
244
245         The passphrase can be given as parameter, using a callback
246         registered at the context, or out-of-band via pinentry.
247
248         Keyword arguments:
249         recipients      -- list of keys to encrypt to
250         sign            -- sign plaintext (default True)
251         sink            -- write result to sink instead of returning it
252         passphrase      -- for symmetric encryption
253         always_trust    -- always trust the keys (default False)
254         add_encrypt_to  -- encrypt to configured additional keys (default False)
255         prepare         -- (ui) prepare for encryption (default False)
256         expect_sign     -- (ui) prepare for signing (default False)
257         compress        -- compress plaintext (default True)
258
259         Returns:
260         ciphertext      -- the encrypted data (or None if sink is given)
261         result          -- additional information about the encryption
262         sign_result     -- additional information about the signature(s)
263
264         Raises:
265         InvalidRecipients -- if encryption using a particular key failed
266         InvalidSigners  -- if signing using a particular key failed
267         GPGMEError      -- as signaled by the underlying library
268
269         """
270         ciphertext = sink if sink else Data()
271         flags = 0
272         flags |= always_trust * constants.ENCRYPT_ALWAYS_TRUST
273         flags |= (not add_encrypt_to) * constants.ENCRYPT_NO_ENCRYPT_TO
274         flags |= prepare * constants.ENCRYPT_PREPARE
275         flags |= expect_sign * constants.ENCRYPT_EXPECT_SIGN
276         flags |= (not compress) * constants.ENCRYPT_NO_COMPRESS
277
278         if passphrase is not None:
279             old_pinentry_mode = self.pinentry_mode
280             old_passphrase_cb = getattr(self, '_passphrase_cb', None)
281             self.pinentry_mode = constants.PINENTRY_MODE_LOOPBACK
282
283             def passphrase_cb(hint, desc, prev_bad, hook=None):
284                 return passphrase
285             self.set_passphrase_cb(passphrase_cb)
286
287         try:
288             if sign:
289                 self.op_encrypt_sign(recipients, flags, plaintext, ciphertext)
290             else:
291                 self.op_encrypt(recipients, flags, plaintext, ciphertext)
292         except errors.GPGMEError as e:
293             result = self.op_encrypt_result()
294             sig_result = self.op_sign_result() if sign else None
295             results = (self.__read__(sink, ciphertext),
296                        result, sig_result)
297             if e.getcode() == errors.UNUSABLE_PUBKEY:
298                 if result.invalid_recipients:
299                     raise errors.InvalidRecipients(result.invalid_recipients,
300                                                    error=e.error,
301                                                    results=results)
302             if e.getcode() == errors.UNUSABLE_SECKEY:
303                 sig_result = self.op_sign_result()
304                 if sig_result.invalid_signers:
305                     raise errors.InvalidSigners(sig_result.invalid_signers,
306                                                 error=e.error,
307                                                 results=results)
308             # Otherwise, just raise the error, but attach the results
309             # first.
310             e.results = results
311             raise e
312         finally:
313             if passphrase is not None:
314                 self.pinentry_mode = old_pinentry_mode
315                 if old_passphrase_cb:
316                     self.set_passphrase_cb(*old_passphrase_cb[1:])
317
318         result = self.op_encrypt_result()
319         assert not result.invalid_recipients
320         sig_result = self.op_sign_result() if sign else None
321         assert not sig_result or not sig_result.invalid_signers
322
323         return self.__read__(sink, ciphertext), result, sig_result
324
325     def decrypt(self, ciphertext, sink=None, passphrase=None, verify=True):
326         """Decrypt data
327
328         Decrypt the given ciphertext and verify any signatures.  If
329         VERIFY is an iterable of keys, the ciphertext must be signed
330         by all those keys, otherwise an error is raised.
331
332         If the ciphertext is symmetrically encrypted using a
333         passphrase, that passphrase can be given as parameter, using a
334         callback registered at the context, or out-of-band via
335         pinentry.
336
337         Keyword arguments:
338         sink            -- write result to sink instead of returning it
339         passphrase      -- for symmetric decryption
340         verify          -- check signatures (default True)
341
342         Returns:
343         plaintext       -- the decrypted data (or None if sink is given)
344         result          -- additional information about the decryption
345         verify_result   -- additional information about the signature(s)
346
347         Raises:
348         UnsupportedAlgorithm -- if an unsupported algorithm was used
349         BadSignatures   -- if a bad signature is encountered
350         MissingSignatures -- if expected signatures are missing or bad
351         GPGMEError      -- as signaled by the underlying library
352
353         """
354         plaintext = sink if sink else Data()
355
356         if passphrase is not None:
357             old_pinentry_mode = self.pinentry_mode
358             old_passphrase_cb = getattr(self, '_passphrase_cb', None)
359             self.pinentry_mode = constants.PINENTRY_MODE_LOOPBACK
360
361             def passphrase_cb(hint, desc, prev_bad, hook=None):
362                 return passphrase
363             self.set_passphrase_cb(passphrase_cb)
364
365         try:
366             if verify:
367                 self.op_decrypt_verify(ciphertext, plaintext)
368             else:
369                 self.op_decrypt(ciphertext, plaintext)
370         except errors.GPGMEError as e:
371             result = self.op_decrypt_result()
372             verify_result = self.op_verify_result() if verify else None
373             # Just raise the error, but attach the results first.
374             e.results = (self.__read__(sink, plaintext),
375                          result, verify_result)
376             raise e
377         finally:
378             if passphrase is not None:
379                 self.pinentry_mode = old_pinentry_mode
380                 if old_passphrase_cb:
381                     self.set_passphrase_cb(*old_passphrase_cb[1:])
382
383         result = self.op_decrypt_result()
384         verify_result = self.op_verify_result() if verify else None
385         results = (self.__read__(sink, plaintext), result, verify_result)
386         if result.unsupported_algorithm:
387             raise errors.UnsupportedAlgorithm(result.unsupported_algorithm,
388                                               results=results)
389
390         if verify:
391             if any(s.status != errors.NO_ERROR
392                    for s in verify_result.signatures):
393                 raise errors.BadSignatures(verify_result, results=results)
394
395         if not verify:  # was: if verify and verify != True:
396             missing = list()
397             for key in verify:
398                 ok = False
399                 for subkey in key.subkeys:
400                     for sig in verify_result.signatures:
401                         if sig.summary & constants.SIGSUM_VALID == 0:
402                             continue
403                         if subkey.can_sign and subkey.fpr == sig.fpr:
404                             ok = True
405                             break
406                     if ok:
407                         break
408                 if not ok:
409                     missing.append(key)
410             if missing:
411                 raise errors.MissingSignatures(verify_result, missing,
412                                                results=results)
413
414         return results
415
416     def sign(self, data, sink=None, mode=constants.SIG_MODE_NORMAL):
417         """Sign data
418
419         Sign the given data with either the configured default local
420         key, or the 'signers' keys of this context.
421
422         Keyword arguments:
423         mode            -- signature mode (default: normal, see below)
424         sink            -- write result to sink instead of returning it
425
426         Returns:
427         either
428           signed_data   -- encoded data and signature (normal mode)
429           signature     -- only the signature data (detached mode)
430           cleartext     -- data and signature as text (cleartext mode)
431             (or None if sink is given)
432         result          -- additional information about the signature(s)
433
434         Raises:
435         InvalidSigners  -- if signing using a particular key failed
436         GPGMEError      -- as signaled by the underlying library
437
438         """
439         signeddata = sink if sink else Data()
440
441         try:
442             self.op_sign(data, signeddata, mode)
443         except errors.GPGMEError as e:
444             results = (self.__read__(sink, signeddata),
445                        self.op_sign_result())
446             if e.getcode() == errors.UNUSABLE_SECKEY:
447                 if results[1].invalid_signers:
448                     raise errors.InvalidSigners(results[1].invalid_signers,
449                                                 error=e.error,
450                                                 results=results)
451             e.results = results
452             raise e
453
454         result = self.op_sign_result()
455         assert not result.invalid_signers
456
457         return self.__read__(sink, signeddata), result
458
459     def verify(self, signed_data, signature=None, sink=None, verify=[]):
460         """Verify signatures
461
462         Verify signatures over data.  If VERIFY is an iterable of
463         keys, the ciphertext must be signed by all those keys,
464         otherwise an error is raised.
465
466         Keyword arguments:
467         signature       -- detached signature data
468         sink            -- write result to sink instead of returning it
469
470         Returns:
471         data            -- the plain data
472             (or None if sink is given, or we verified a detached signature)
473         result          -- additional information about the signature(s)
474
475         Raises:
476         BadSignatures   -- if a bad signature is encountered
477         MissingSignatures -- if expected signatures are missing or bad
478         GPGMEError      -- as signaled by the underlying library
479
480         """
481         if signature:
482             # Detached signature, we don't return the plain text.
483             data = None
484         else:
485             data = sink if sink else Data()
486
487         try:
488             if signature:
489                 self.op_verify(signature, signed_data, None)
490             else:
491                 self.op_verify(signed_data, None, data)
492         except errors.GPGMEError as e:
493             # Just raise the error, but attach the results first.
494             e.results = (self.__read__(sink, data),
495                          self.op_verify_result())
496             raise e
497
498         results = (self.__read__(sink, data), self.op_verify_result())
499         if any(s.status != errors.NO_ERROR for s in results[1].signatures):
500             raise errors.BadSignatures(results[1], results=results)
501
502         missing = list()
503         for key in verify:
504             ok = False
505             for subkey in key.subkeys:
506                 for sig in results[1].signatures:
507                     if sig.summary & constants.SIGSUM_VALID == 0:
508                         continue
509                     if subkey.can_sign and subkey.fpr == sig.fpr:
510                         ok = True
511                         break
512                 if ok:
513                     break
514             if not ok:
515                 missing.append(key)
516         if missing:
517             raise errors.MissingSignatures(results[1], missing,
518                                            results=results)
519
520         return results
521
522     def key_import(self, data):
523         """Import data
524
525         Imports the given data into the Context.
526
527         Returns:
528                 -- an object describing the results of imported or updated
529                    keys
530
531         Raises:
532         TypeError      -- Very rarely.
533         GPGMEError     -- as signaled by the underlying library:
534
535                           Import status errors, when they occur, will usually
536                           be of NODATA.  NO_PUBKEY indicates something
537                           managed to run the function without any
538                           arguments, while an argument of None triggers
539                           the first NODATA of errors.GPGME in the
540                           exception.
541         """
542         try:
543             self.op_import(data)
544             result = self.op_import_result()
545             if result.considered == 0:
546                 status = constants.STATUS_IMPORT_PROBLEM
547             else:
548                 status = constants.STATUS_KEY_CONSIDERED
549         except Exception as e:
550             if e == errors.GPGMEError:
551                 if e.code_str == "No data":
552                     status = constants.STATUS_NODATA
553                 else:
554                     status = constants.STATUS_FILE_ERROR
555             elif e == TypeError and hasattr(data, "decode") is True:
556                 status = constants.STATUS_NO_PUBKEY
557             elif e == TypeError and hasattr(data, "encode") is True:
558                 status = constants.STATUS_FILE_ERROR
559             else:
560                 status = constants.STATUS_ERROR
561
562         if status == constants.STATUS_KEY_CONSIDERED:
563             import_result = result
564         else:
565             import_result = status
566
567         return import_result
568
569     def key_export(self, pattern=None):
570         """Export keys.
571
572         Exports public keys matching the pattern specified.  If no
573         pattern is specified then exports all available keys.
574
575         Keyword arguments:
576         pattern -- return keys matching pattern (default: all keys)
577
578         Returns:
579                 -- A key block containing one or more OpenPGP keys in
580                    either ASCII armoured or binary format as determined
581                    by the Context().  If there are no matching keys it
582                    returns None.
583
584         Raises:
585         GPGMEError     -- as signaled by the underlying library.
586         """
587         data = Data()
588         mode = 0
589         try:
590             self.op_export(pattern, mode, data)
591             data.seek(0, os.SEEK_SET)
592             pk_result = data.read()
593         except GPGMEError as e:
594             pk_result = e
595
596         if len(pk_result) > 0:
597             result = pk_result
598         else:
599             result = None
600
601         return result
602
603     def key_export_minimal(self, pattern=None):
604         """Export keys.
605
606         Exports public keys matching the pattern specified in a
607         minimised format.  If no pattern is specified then exports all
608         available keys.
609
610         Keyword arguments:
611         pattern -- return keys matching pattern (default: all keys)
612
613         Returns:
614                 -- A key block containing one or more minimised OpenPGP
615                    keys in either ASCII armoured or binary format as
616                    determined by the Context().  If there are no matching
617                    keys it returns None.
618
619         Raises:
620         GPGMEError     -- as signaled by the underlying library.
621         """
622         data = Data()
623         mode = gpgme.GPGME_EXPORT_MODE_MINIMAL
624         try:
625             self.op_export(pattern, mode, data)
626             data.seek(0, os.SEEK_SET)
627             pk_result = data.read()
628         except GPGMEError as e:
629             pk_result = e
630
631         if len(pk_result) > 0:
632             result = pk_result
633         else:
634             result = None
635
636         return result
637
638     def key_export_secret(self, pattern=None):
639         """Export secret keys.
640
641         Exports secret keys matching the pattern specified.  If no
642         pattern is specified then exports or attempts to export all
643         available secret keys.
644
645         IMPORTANT: Each secret key to be exported will prompt for its
646         passphrase via an invocation of pinentry and gpg-agent.  If the
647         passphrase is not entered or does not match then no data will be
648         exported.  This is the same result as when specifying a pattern
649         that is not matched by the available keys.
650
651         Keyword arguments:
652         pattern -- return keys matching pattern (default: all keys)
653
654         Returns:
655                 -- On success a key block containing one or more OpenPGP
656                    secret keys in either ASCII armoured or binary format
657                    as determined by the Context().
658                 -- On failure while not raising an exception, returns None.
659
660         Raises:
661         GPGMEError     -- as signaled by the underlying library.
662         """
663         data = Data()
664         mode = gpgme.GPGME_EXPORT_MODE_SECRET
665         try:
666             self.op_export(pattern, mode, data)
667             data.seek(0, os.SEEK_SET)
668             sk_result = data.read()
669         except GPGMEError as e:
670             sk_result = e
671
672         if len(sk_result) > 0:
673             result = sk_result
674         else:
675             result = None
676
677         return result
678
679     def keylist(self, pattern=None, secret=False,
680                 mode=constants.keylist.mode.LOCAL,
681                 source=None):
682         """List keys
683
684         Keyword arguments:
685         pattern -- return keys matching pattern (default: all keys)
686         secret  -- return only secret keys (default: False)
687         mode    -- keylist mode (default: list local keys)
688         source  -- read keys from source instead from the keyring
689                        (all other options are ignored in this case)
690
691         Returns:
692                 -- an iterator returning key objects
693
694         Raises:
695         GPGMEError      -- as signaled by the underlying library
696         """
697         if not source:
698             self.set_keylist_mode(mode)
699             self.op_keylist_start(pattern, secret)
700         else:
701             # Automatic wrapping of SOURCE is not possible here,
702             # because the object must not be deallocated until the
703             # iteration over the results ends.
704             if not isinstance(source, Data):
705                 source = Data(file=source)
706             self.op_keylist_from_data_start(source, 0)
707
708         key = self.op_keylist_next()
709         while key:
710             yield key
711             key = self.op_keylist_next()
712         self.op_keylist_end()
713
714     def create_key(self, userid, algorithm=None, expires_in=0, expires=True,
715                    sign=False, encrypt=False, certify=False,
716                    authenticate=False, passphrase=None, force=False):
717         """Create a primary key
718
719         Create a primary key for the user id USERID.
720
721         ALGORITHM may be used to specify the public key encryption
722         algorithm for the new key.  By default, a reasonable default
723         is chosen.  You may use "future-default" to select an
724         algorithm that will be the default in a future implementation
725         of the engine.  ALGORITHM may be a string like "rsa", or
726         "rsa2048" to explicitly request an algorithm and a key size.
727
728         EXPIRES_IN specifies the expiration time of the key in number
729         of seconds since the keys creation.  By default, a reasonable
730         expiration time is chosen.  If you want to create a key that
731         does not expire, use the keyword argument EXPIRES.
732
733         SIGN, ENCRYPT, CERTIFY, and AUTHENTICATE can be used to
734         request the capabilities of the new key.  If you don't request
735         any, a reasonable set of capabilities is selected, and in case
736         of OpenPGP, a subkey with a reasonable set of capabilities is
737         created.
738
739         If PASSPHRASE is None (the default), then the key will not be
740         protected with a passphrase.  If PASSPHRASE is a string, it
741         will be used to protect the key.  If PASSPHRASE is True, the
742         passphrase must be supplied using a passphrase callback or
743         out-of-band with a pinentry.
744
745         Keyword arguments:
746         algorithm    -- public key algorithm, see above (default: reasonable)
747         expires_in   -- expiration time in seconds (default: reasonable)
748         expires      -- whether or not the key should expire (default: True)
749         sign         -- request the signing capability (see above)
750         encrypt      -- request the encryption capability (see above)
751         certify      -- request the certification capability (see above)
752         authenticate -- request the authentication capability (see above)
753         passphrase   -- protect the key with a passphrase (default: no
754                         passphrase)
755         force        -- force key creation even if a key with the same userid
756                         exists (default: False)
757
758         Returns:
759                      -- an object describing the result of the key creation
760
761         Raises:
762         GPGMEError   -- as signaled by the underlying library
763
764         """
765         if util.is_a_string(passphrase):
766             old_pinentry_mode = self.pinentry_mode
767             old_passphrase_cb = getattr(self, '_passphrase_cb', None)
768             self.pinentry_mode = constants.PINENTRY_MODE_LOOPBACK
769
770             def passphrase_cb(hint, desc, prev_bad, hook=None):
771                 return passphrase
772             self.set_passphrase_cb(passphrase_cb)
773
774         try:
775             self.op_createkey(userid, algorithm,
776                               0,  # reserved
777                               expires_in,
778                               None,  # extrakey
779                               ((constants.create.SIGN if sign else 0)
780                                | (constants.create.ENCR if encrypt else 0)
781                                | (constants.create.CERT if certify else 0)
782                                | (constants.create.AUTH if authenticate else 0)
783                                | (constants.create.NOPASSWD if passphrase is None else 0)
784                                | (0 if expires else constants.create.NOEXPIRE)
785                                | (constants.create.FORCE if force else 0)))
786         finally:
787             if util.is_a_string(passphrase):
788                 self.pinentry_mode = old_pinentry_mode
789                 if old_passphrase_cb:
790                     self.set_passphrase_cb(*old_passphrase_cb[1:])
791
792         return self.op_genkey_result()
793
794     def create_subkey(self, key, algorithm=None, expires_in=0, expires=True,
795                       sign=False, encrypt=False, authenticate=False,
796                       passphrase=None):
797         """Create a subkey
798
799         Create a subkey for the given KEY.  As subkeys are a concept
800         of OpenPGP, calling this is only valid for the OpenPGP
801         protocol.
802
803         ALGORITHM may be used to specify the public key encryption
804         algorithm for the new subkey.  By default, a reasonable
805         default is chosen.  You may use "future-default" to select an
806         algorithm that will be the default in a future implementation
807         of the engine.  ALGORITHM may be a string like "rsa", or
808         "rsa2048" to explicitly request an algorithm and a key size.
809
810         EXPIRES_IN specifies the expiration time of the subkey in
811         number of seconds since the subkeys creation.  By default, a
812         reasonable expiration time is chosen.  If you want to create a
813         subkey that does not expire, use the keyword argument EXPIRES.
814
815         SIGN, ENCRYPT, and AUTHENTICATE can be used to request the
816         capabilities of the new subkey.  If you don't request any, an
817         encryption subkey is generated.
818
819         If PASSPHRASE is None (the default), then the subkey will not
820         be protected with a passphrase.  If PASSPHRASE is a string, it
821         will be used to protect the subkey.  If PASSPHRASE is True,
822         the passphrase must be supplied using a passphrase callback or
823         out-of-band with a pinentry.
824
825         Keyword arguments:
826         algorithm    -- public key algorithm, see above (default: reasonable)
827         expires_in   -- expiration time in seconds (default: reasonable)
828         expires      -- whether or not the subkey should expire (default: True)
829         sign         -- request the signing capability (see above)
830         encrypt      -- request the encryption capability (see above)
831         authenticate -- request the authentication capability (see above)
832         passphrase   -- protect the subkey with a passphrase (default: no
833                         passphrase)
834
835         Returns:
836                      -- an object describing the result of the subkey creation
837
838         Raises:
839         GPGMEError   -- as signaled by the underlying library
840
841         """
842         if util.is_a_string(passphrase):
843             old_pinentry_mode = self.pinentry_mode
844             old_passphrase_cb = getattr(self, '_passphrase_cb', None)
845             self.pinentry_mode = constants.PINENTRY_MODE_LOOPBACK
846
847             def passphrase_cb(hint, desc, prev_bad, hook=None):
848                 return passphrase
849             self.set_passphrase_cb(passphrase_cb)
850
851         try:
852             self.op_createsubkey(key, algorithm,
853                                  0,  # reserved
854                                  expires_in,
855                                  ((constants.create.SIGN if sign else 0)
856                                   | (constants.create.ENCR if encrypt else 0)
857                                   | (constants.create.AUTH if authenticate else 0)
858                                   | (constants.create.NOPASSWD
859                                      if passphrase is None else 0)
860                                   | (0 if expires else constants.create.NOEXPIRE)))
861         finally:
862             if util.is_a_string(passphrase):
863                 self.pinentry_mode = old_pinentry_mode
864                 if old_passphrase_cb:
865                     self.set_passphrase_cb(*old_passphrase_cb[1:])
866
867         return self.op_genkey_result()
868
869     def key_add_uid(self, key, uid):
870         """Add a UID
871
872         Add the uid UID to the given KEY.  Calling this function is
873         only valid for the OpenPGP protocol.
874
875         Raises:
876         GPGMEError   -- as signaled by the underlying library
877
878         """
879         self.op_adduid(key, uid, 0)
880
881     def key_revoke_uid(self, key, uid):
882         """Revoke a UID
883
884         Revoke the uid UID from the given KEY.  Calling this function
885         is only valid for the OpenPGP protocol.
886
887         Raises:
888         GPGMEError   -- as signaled by the underlying library
889
890         """
891         self.op_revuid(key, uid, 0)
892
893     def key_sign(self, key, uids=None, expires_in=False, local=False):
894         """Sign a key
895
896         Sign a key with the current set of signing keys.  Calling this
897         function is only valid for the OpenPGP protocol.
898
899         If UIDS is None (the default), then all UIDs are signed.  If
900         it is a string, then only the matching UID is signed.  If it
901         is a list of strings, then all matching UIDs are signed.  Note
902         that a case-sensitive exact string comparison is done.
903
904         EXPIRES_IN specifies the expiration time of the signature in
905         seconds.  If EXPIRES_IN is False, the signature does not
906         expire.
907
908         Keyword arguments:
909         uids         -- user ids to sign, see above (default: sign all)
910         expires_in   -- validity period of the signature in seconds
911                                                (default: do not expire)
912         local        -- create a local, non-exportable signature
913                                                (default: False)
914
915         Raises:
916         GPGMEError   -- as signaled by the underlying library
917
918         """
919         flags = 0
920         if uids is None or util.is_a_string(uids):
921             pass  # through unchanged
922         else:
923             flags |= constants.keysign.LFSEP
924             uids = "\n".join(uids)
925
926         if not expires_in:
927             flags |= constants.keysign.NOEXPIRE
928
929         if local:
930             flags |= constants.keysign.LOCAL
931
932         self.op_keysign(key, uids, expires_in, flags)
933
934     def key_tofu_policy(self, key, policy):
935         """Set a keys' TOFU policy
936
937         Set the TOFU policy associated with KEY to POLICY.  Calling
938         this function is only valid for the OpenPGP protocol.
939
940         Raises:
941         GPGMEError   -- as signaled by the underlying library
942
943         """
944         self.op_tofu_policy(key, policy)
945
946     def assuan_transact(self, command,
947                         data_cb=None, inquire_cb=None, status_cb=None):
948         """Issue a raw assuan command
949
950         This function can be used to issue a raw assuan command to the
951         engine.
952
953         If command is a string or bytes, it will be used as-is.  If it
954         is an iterable of strings, it will be properly escaped and
955         joined into an well-formed assuan command.
956
957         Keyword arguments:
958         data_cb         -- a callback receiving data lines
959         inquire_cb      -- a callback providing more information
960         status_cb       -- a callback receiving status lines
961
962         Returns:
963         result          -- the result of command as GPGMEError
964
965         Raises:
966         GPGMEError      -- as signaled by the underlying library
967
968         """
969
970         if util.is_a_string(command) or isinstance(command, bytes):
971             cmd = command
972         else:
973             cmd = " ".join(util.percent_escape(f) for f in command)
974
975         errptr = gpgme.new_gpgme_error_t_p()
976
977         err = gpgme.gpgme_op_assuan_transact_ext(
978             self.wrapped,
979             cmd,
980             (weakref.ref(self), data_cb) if data_cb else None,
981             (weakref.ref(self), inquire_cb) if inquire_cb else None,
982             (weakref.ref(self), status_cb) if status_cb else None,
983             errptr)
984
985         if self._callback_excinfo:
986             gpgme.gpg_raise_callback_exception(self)
987
988         errorcheck(err)
989
990         status = gpgme.gpgme_error_t_p_value(errptr)
991         gpgme.delete_gpgme_error_t_p(errptr)
992
993         return GPGMEError(status) if status != 0 else None
994
995     def interact(self, key, func, sink=None, flags=0, fnc_value=None):
996         """Interact with the engine
997
998         This method can be used to edit keys and cards interactively.
999         KEY is the key to edit, FUNC is called repeatedly with two
1000         unicode arguments, 'keyword' and 'args'.  See the GPGME manual
1001         for details.
1002
1003         Keyword arguments:
1004         sink            -- if given, additional output is written here
1005         flags           -- use constants.INTERACT_CARD to edit a card
1006
1007         Raises:
1008         GPGMEError      -- as signaled by the underlying library
1009
1010         """
1011         if key is None:
1012             raise ValueError("First argument cannot be None")
1013
1014         if sink is None:
1015             sink = Data()
1016
1017         if fnc_value:
1018             opaquedata = (weakref.ref(self), func, fnc_value)
1019         else:
1020             opaquedata = (weakref.ref(self), func)
1021
1022         result = gpgme.gpgme_op_interact(self.wrapped, key, flags,
1023                                          opaquedata, sink)
1024         if self._callback_excinfo:
1025             gpgme.gpg_raise_callback_exception(self)
1026         errorcheck(result)
1027
1028     @property
1029     def signers(self):
1030         """Keys used for signing"""
1031         return [self.signers_enum(i) for i in range(self.signers_count())]
1032
1033     @signers.setter
1034     def signers(self, signers):
1035         old = self.signers
1036         self.signers_clear()
1037         try:
1038             for key in signers:
1039                 self.signers_add(key)
1040         except:
1041             self.signers = old
1042             raise
1043
1044     @property
1045     def pinentry_mode(self):
1046         """Pinentry mode"""
1047         return self.get_pinentry_mode()
1048
1049     @pinentry_mode.setter
1050     def pinentry_mode(self, value):
1051         self.set_pinentry_mode(value)
1052
1053     @property
1054     def protocol(self):
1055         """Protocol to use"""
1056         return self.get_protocol()
1057
1058     @protocol.setter
1059     def protocol(self, value):
1060         errorcheck(gpgme.gpgme_engine_check_version(value))
1061         self.set_protocol(value)
1062
1063     @property
1064     def home_dir(self):
1065         """Engine's home directory"""
1066         return self.engine_info.home_dir
1067
1068     @home_dir.setter
1069     def home_dir(self, value):
1070         self.set_engine_info(self.protocol, home_dir=value)
1071
1072     _ctype = 'gpgme_ctx_t'
1073     _cprefix = 'gpgme_'
1074
1075     def _errorcheck(self, name):
1076         """This function should list all functions returning gpgme_error_t"""
1077         # The list of functions is created using:
1078         #
1079         # $ grep '^gpgme_error_t ' obj/lang/python/python3.5-gpg/gpgme.h \
1080         # | grep -v _op_ | awk "/\(gpgme_ctx/ { printf (\"'%s',\\n\", \$2) } "
1081         return ((name.startswith('gpgme_op_') and not
1082             name.endswith('_result')) or name in {'gpgme_new',
1083             'gpgme_set_ctx_flag', 'gpgme_set_protocol',
1084             'gpgme_set_sub_protocol', 'gpgme_set_keylist_mode',
1085             'gpgme_set_pinentry_mode', 'gpgme_set_locale',
1086             'gpgme_ctx_set_engine_info', 'gpgme_signers_add',
1087             'gpgme_sig_notation_add', 'gpgme_set_sender', 'gpgme_cancel',
1088             'gpgme_cancel_async', 'gpgme_get_key'})
1089
1090     _boolean_properties = {'armor', 'textmode', 'offline'}
1091
1092     def __del__(self):
1093         if not gpgme:
1094             # At interpreter shutdown, gpgme is set to NONE.
1095             return
1096
1097         self._free_passcb()
1098         self._free_progresscb()
1099         self._free_statuscb()
1100         if self.own and self.wrapped and gpgme.gpgme_release:
1101             gpgme.gpgme_release(self.wrapped)
1102             self.wrapped = None
1103
1104     # Implement the context manager protocol.
1105     def __enter__(self):
1106         return self
1107
1108     def __exit__(self, type, value, tb):
1109         self.__del__()
1110
1111     def op_keylist_all(self, *args, **kwargs):
1112         self.op_keylist_start(*args, **kwargs)
1113         key = self.op_keylist_next()
1114         while key:
1115             yield key
1116             key = self.op_keylist_next()
1117         self.op_keylist_end()
1118
1119     def op_keylist_next(self):
1120         """Returns the next key in the list created
1121         by a call to op_keylist_start().  The object returned
1122         is of type Key."""
1123         ptr = gpgme.new_gpgme_key_t_p()
1124         try:
1125             errorcheck(gpgme.gpgme_op_keylist_next(self.wrapped, ptr))
1126             key = gpgme.gpgme_key_t_p_value(ptr)
1127         except errors.GPGMEError as excp:
1128             key = None
1129             if excp.getcode() != errors.EOF:
1130                 raise excp
1131         gpgme.delete_gpgme_key_t_p(ptr)
1132         if key:
1133             key.__del__ = lambda self: gpgme.gpgme_key_unref(self)
1134             return key
1135
1136     def get_key(self, fpr, secret=False):
1137         """Get a key given a fingerprint
1138
1139         Keyword arguments:
1140         secret          -- to request a secret key
1141
1142         Returns:
1143                         -- the matching key
1144
1145         Raises:
1146         KeyError        -- if the key was not found
1147         GPGMEError      -- as signaled by the underlying library
1148
1149         """
1150         ptr = gpgme.new_gpgme_key_t_p()
1151
1152         try:
1153             errorcheck(gpgme.gpgme_get_key(self.wrapped, fpr, ptr, secret))
1154         except errors.GPGMEError as e:
1155             if e.getcode() == errors.EOF:
1156                 raise errors.KeyNotFound(fpr)
1157             raise e
1158
1159         key = gpgme.gpgme_key_t_p_value(ptr)
1160         gpgme.delete_gpgme_key_t_p(ptr)
1161         assert key
1162         key.__del__ = lambda self: gpgme.gpgme_key_unref(self)
1163         return key
1164
1165     def op_trustlist_all(self, *args, **kwargs):
1166         self.op_trustlist_start(*args, **kwargs)
1167         trust = self.op_trustlist_next()
1168         while trust:
1169             yield trust
1170             trust = self.op_trustlist_next()
1171         self.op_trustlist_end()
1172
1173     def op_trustlist_next(self):
1174         """Returns the next trust item in the list created
1175         by a call to op_trustlist_start().  The object returned
1176         is of type TrustItem."""
1177         ptr = gpgme.new_gpgme_trust_item_t_p()
1178         try:
1179             errorcheck(gpgme.gpgme_op_trustlist_next(self.wrapped, ptr))
1180             trust = gpgme.gpgme_trust_item_t_p_value(ptr)
1181         except errors.GPGMEError as excp:
1182             trust = None
1183             if excp.getcode() != errors.EOF:
1184                 raise
1185         gpgme.delete_gpgme_trust_item_t_p(ptr)
1186         return trust
1187
1188     def set_passphrase_cb(self, func, hook=None):
1189         """Sets the passphrase callback to the function specified by func.
1190
1191         When the system needs a passphrase, it will call func with three args:
1192         hint, a string describing the key it needs the passphrase for;
1193         desc, a string describing the passphrase it needs;
1194         prev_bad, a boolean equal True if this is a call made after
1195         unsuccessful previous attempt.
1196
1197         If hook has a value other than None it will be passed into the func
1198         as a forth argument.
1199
1200         Please see the GPGME manual for more information.
1201         """
1202         if func is None:
1203             hookdata = None
1204         else:
1205             if hook is None:
1206                 hookdata = (weakref.ref(self), func)
1207             else:
1208                 hookdata = (weakref.ref(self), func, hook)
1209         gpgme.gpg_set_passphrase_cb(self, hookdata)
1210
1211     def _free_passcb(self):
1212         if gpgme.gpg_set_passphrase_cb:
1213             self.set_passphrase_cb(None)
1214
1215     def set_progress_cb(self, func, hook=None):
1216         """Sets the progress meter callback to the function specified by FUNC.
1217         If FUNC is None, the callback will be cleared.
1218
1219         This function will be called to provide an interactive update
1220         of the system's progress.  The function will be called with
1221         three arguments, type, total, and current.  If HOOK is not
1222         None, it will be supplied as fourth argument.
1223
1224         Please see the GPGME manual for more information.
1225
1226         """
1227         if func is None:
1228             hookdata = None
1229         else:
1230             if hook is None:
1231                 hookdata = (weakref.ref(self), func)
1232             else:
1233                 hookdata = (weakref.ref(self), func, hook)
1234         gpgme.gpg_set_progress_cb(self, hookdata)
1235
1236     def _free_progresscb(self):
1237         if gpgme.gpg_set_progress_cb:
1238             self.set_progress_cb(None)
1239
1240     def set_status_cb(self, func, hook=None):
1241         """Sets the status callback to the function specified by FUNC.  If
1242         FUNC is None, the callback will be cleared.
1243
1244         The function will be called with two arguments, keyword and
1245         args.  If HOOK is not None, it will be supplied as third
1246         argument.
1247
1248         Please see the GPGME manual for more information.
1249
1250         """
1251         if func is None:
1252             hookdata = None
1253         else:
1254             if hook is None:
1255                 hookdata = (weakref.ref(self), func)
1256             else:
1257                 hookdata = (weakref.ref(self), func, hook)
1258         gpgme.gpg_set_status_cb(self, hookdata)
1259
1260     def _free_statuscb(self):
1261         if gpgme.gpg_set_status_cb:
1262             self.set_status_cb(None)
1263
1264     @property
1265     def engine_info(self):
1266         """Configuration of the engine currently in use"""
1267         p = self.protocol
1268         infos = [i for i in self.get_engine_info() if i.protocol == p]
1269         assert len(infos) == 1
1270         return infos[0]
1271
1272     def get_engine_info(self):
1273         """Get engine configuration
1274
1275         Returns information about all configured and installed
1276         engines.
1277
1278         Returns:
1279         infos           -- a list of engine infos
1280
1281         """
1282         return gpgme.gpgme_ctx_get_engine_info(self.wrapped)
1283
1284     def set_engine_info(self, proto, file_name=None, home_dir=None):
1285         """Change engine configuration
1286
1287         Changes the configuration of the crypto engine implementing
1288         the protocol 'proto' for the context.
1289
1290         Keyword arguments:
1291         file_name       -- engine program file name (unchanged if None)
1292         home_dir        -- configuration directory (unchanged if None)
1293
1294         """
1295         self.ctx_set_engine_info(proto, file_name, home_dir)
1296
1297     def wait(self, hang):
1298         """Wait for asynchronous call to finish. Wait forever if hang is True.
1299         Raises an exception on errors.
1300
1301         Please read the GPGME manual for more information.
1302
1303         """
1304         ptr = gpgme.new_gpgme_error_t_p()
1305         gpgme.gpgme_wait(self.wrapped, ptr, hang)
1306         status = gpgme.gpgme_error_t_p_value(ptr)
1307         gpgme.delete_gpgme_error_t_p(ptr)
1308         errorcheck(status)
1309
1310     def op_edit(self, key, func, fnc_value, out):
1311         """Start key editing using supplied callback function
1312
1313         Note: This interface is deprecated and will be removed with
1314         GPGME 1.8.  Please use .interact instead.  Furthermore, we
1315         implement this using gpgme_op_interact, so callbacks will get
1316         called with string keywords instead of numeric status
1317         messages.  Code that is using constants.STATUS_X or
1318         constants.status.X will continue to work, whereas code using
1319         magic numbers will break as a result.
1320
1321         """
1322         warnings.warn("Call to deprecated method op_edit.",
1323                       category=DeprecationWarning)
1324         return self.interact(key, func, sink=out, fnc_value=fnc_value)
1325
1326
1327 class Data(GpgmeWrapper):
1328     """Data buffer
1329
1330     A lot of data has to be exchanged between the user and the crypto
1331     engine, like plaintext messages, ciphertext, signatures and
1332     information about the keys.  The technical details about
1333     exchanging the data information are completely abstracted by
1334     GPGME.  The user provides and receives the data via `gpgme_data_t'
1335     objects, regardless of the communication protocol between GPGME
1336     and the crypto engine in use.
1337
1338     This Data class is the implementation of the GpgmeData objects.
1339
1340     Please see the information about __init__ for instantiation.
1341
1342     """
1343
1344     _ctype = 'gpgme_data_t'
1345     _cprefix = 'gpgme_data_'
1346
1347     def _errorcheck(self, name):
1348         """This function should list all functions returning gpgme_error_t"""
1349         # This list is compiled using
1350         #
1351         # $ grep -v '^gpgme_error_t ' obj/lang/python/python3.5-gpg/gpgme.h \
1352         #   | awk "/\(gpgme_data_t/ { printf (\"'%s',\\n\", \$2) } " \
1353         #   | sed "s/'\\*/'/"
1354         return name not in {
1355             'gpgme_data_read',
1356             'gpgme_data_write',
1357             'gpgme_data_seek',
1358             'gpgme_data_release',
1359             'gpgme_data_release_and_get_mem',
1360             'gpgme_data_get_encoding',
1361             'gpgme_data_get_file_name',
1362             'gpgme_data_identify',
1363         }
1364
1365     def __init__(self, string=None, file=None, offset=None,
1366                  length=None, cbs=None, copy=True):
1367         """Initialize a new gpgme_data_t object.
1368
1369         If no args are specified, make it an empty object.
1370
1371         If string alone is specified, initialize it with the data
1372         contained there.
1373
1374         If file, offset, and length are all specified, file must
1375         be either a filename or a file-like object, and the object
1376         will be initialized by reading the specified chunk from the file.
1377
1378         If cbs is specified, it MUST be a tuple of the form:
1379
1380         (read_cb, write_cb, seek_cb, release_cb[, hook])
1381
1382         where the first four items are functions implementing reading,
1383         writing, seeking the data, and releasing any resources once
1384         the data object is deallocated.  The functions must match the
1385         following prototypes:
1386
1387             def read(amount, hook=None):
1388                 return <a b"bytes" object>
1389
1390             def write(data, hook=None):
1391                 return <the number of bytes written>
1392
1393             def seek(offset, whence, hook=None):
1394                 return <the new file position>
1395
1396             def release(hook=None):
1397                 <return value and exceptions are ignored>
1398
1399         The functions may be bound methods.  In that case, you can
1400         simply use the 'self' reference instead of using a hook.
1401
1402         If file is specified without any other arguments, then
1403         it must be a filename, and the object will be initialized from
1404         that file.
1405
1406         """
1407         super(Data, self).__init__(None)
1408         self.data_cbs = None
1409
1410         if cbs is not None:
1411             self.new_from_cbs(*cbs)
1412         elif string is not None:
1413             self.new_from_mem(string, copy)
1414         elif file is not None and offset is not None and length is not None:
1415             self.new_from_filepart(file, offset, length)
1416         elif file is not None:
1417             if util.is_a_string(file):
1418                 self.new_from_file(file, copy)
1419             else:
1420                 self.new_from_fd(file)
1421         else:
1422             self.new()
1423
1424     def __del__(self):
1425         if not gpgme:
1426             # At interpreter shutdown, gpgme is set to NONE.
1427             return
1428
1429         if self.wrapped is not None and gpgme.gpgme_data_release:
1430             gpgme.gpgme_data_release(self.wrapped)
1431             if self._callback_excinfo:
1432                 gpgme.gpg_raise_callback_exception(self)
1433             self.wrapped = None
1434         self._free_datacbs()
1435
1436     # Implement the context manager protocol.
1437     def __enter__(self):
1438         return self
1439
1440     def __exit__(self, type, value, tb):
1441         self.__del__()
1442
1443     def _free_datacbs(self):
1444         self._data_cbs = None
1445
1446     def new(self):
1447         tmp = gpgme.new_gpgme_data_t_p()
1448         errorcheck(gpgme.gpgme_data_new(tmp))
1449         self.wrapped = gpgme.gpgme_data_t_p_value(tmp)
1450         gpgme.delete_gpgme_data_t_p(tmp)
1451
1452     def new_from_mem(self, string, copy=True):
1453         tmp = gpgme.new_gpgme_data_t_p()
1454         errorcheck(gpgme.gpgme_data_new_from_mem(tmp, string, len(string),
1455                                                  copy))
1456         self.wrapped = gpgme.gpgme_data_t_p_value(tmp)
1457         gpgme.delete_gpgme_data_t_p(tmp)
1458
1459     def new_from_file(self, filename, copy=True):
1460         tmp = gpgme.new_gpgme_data_t_p()
1461         try:
1462             errorcheck(gpgme.gpgme_data_new_from_file(tmp, filename, copy))
1463         except errors.GPGMEError as e:
1464             if e.getcode() == errors.INV_VALUE and not copy:
1465                 raise ValueError("delayed reads are not yet supported")
1466             else:
1467                 raise e
1468         self.wrapped = gpgme.gpgme_data_t_p_value(tmp)
1469         gpgme.delete_gpgme_data_t_p(tmp)
1470
1471     def new_from_cbs(self, read_cb, write_cb, seek_cb, release_cb, hook=None):
1472         tmp = gpgme.new_gpgme_data_t_p()
1473         if hook is not None:
1474             hookdata = (weakref.ref(self),
1475                         read_cb, write_cb, seek_cb, release_cb, hook)
1476         else:
1477             hookdata = (weakref.ref(self),
1478                         read_cb, write_cb, seek_cb, release_cb)
1479         gpgme.gpg_data_new_from_cbs(self, hookdata, tmp)
1480         self.wrapped = gpgme.gpgme_data_t_p_value(tmp)
1481         gpgme.delete_gpgme_data_t_p(tmp)
1482
1483     def new_from_filepart(self, file, offset, length):
1484         """This wraps the GPGME gpgme_data_new_from_filepart() function.
1485         The argument "file" may be:
1486
1487         * a string specifying a file name, or
1488         * a file-like object supporting the fileno() and the mode attribute.
1489
1490         """
1491
1492         tmp = gpgme.new_gpgme_data_t_p()
1493         filename = None
1494         fp = None
1495
1496         if util.is_a_string(file):
1497             filename = file
1498         else:
1499             fp = gpgme.fdopen(file.fileno(), file.mode)
1500             if fp is None:
1501                 raise ValueError("Failed to open file from %s arg %s" %
1502                                  (str(type(file)), str(file)))
1503
1504         errorcheck(gpgme.gpgme_data_new_from_filepart(tmp, filename, fp,
1505                                                       offset, length))
1506         self.wrapped = gpgme.gpgme_data_t_p_value(tmp)
1507         gpgme.delete_gpgme_data_t_p(tmp)
1508
1509     def new_from_fd(self, file):
1510         """This wraps the GPGME gpgme_data_new_from_fd() function.  The
1511         argument "file" must be a file-like object, supporting the
1512         fileno() method.
1513
1514         """
1515         tmp = gpgme.new_gpgme_data_t_p()
1516         errorcheck(gpgme.gpgme_data_new_from_fd(tmp, file.fileno()))
1517         self.wrapped = gpgme.gpgme_data_t_p_value(tmp)
1518         gpgme.delete_gpgme_data_t_p(tmp)
1519
1520     def new_from_stream(self, file):
1521         """This wrap around gpgme_data_new_from_stream is an alias for
1522         new_from_fd() method since in python there's not difference
1523         between file stream and file descriptor"""
1524         self.new_from_fd(file)
1525
1526     def write(self, buffer):
1527         """Write buffer given as string or bytes.
1528
1529         If a string is given, it is implicitly encoded using UTF-8."""
1530         written = gpgme.gpgme_data_write(self.wrapped, buffer)
1531         if written < 0:
1532             if self._callback_excinfo:
1533                 gpgme.gpg_raise_callback_exception(self)
1534             else:
1535                 raise GPGMEError.fromSyserror()
1536         return written
1537
1538     def read(self, size=-1):
1539         """Read at most size bytes, returned as bytes.
1540
1541         If the size argument is negative or omitted, read until EOF is reached.
1542
1543         Returns the data read, or the empty string if there was no data
1544         to read before EOF was reached."""
1545
1546         if size == 0:
1547             return ''
1548
1549         if size > 0:
1550             try:
1551                 result = gpgme.gpgme_data_read(self.wrapped, size)
1552             except:
1553                 if self._callback_excinfo:
1554                     gpgme.gpg_raise_callback_exception(self)
1555                 else:
1556                     raise
1557             return result
1558         else:
1559             chunks = []
1560             while True:
1561                 try:
1562                     result = gpgme.gpgme_data_read(self.wrapped, 4096)
1563                 except:
1564                     if self._callback_excinfo:
1565                         gpgme.gpg_raise_callback_exception(self)
1566                     else:
1567                         raise
1568                 if len(result) == 0:
1569                     break
1570                 chunks.append(result)
1571             return b''.join(chunks)
1572
1573
1574 def pubkey_algo_string(subkey):
1575     """Return short algorithm string
1576
1577     Return a public key algorithm string (e.g. "rsa2048") for a given
1578     SUBKEY.
1579
1580     Returns:
1581     algo      - a string
1582
1583     """
1584     return gpgme.gpgme_pubkey_algo_string(subkey)
1585
1586
1587 def pubkey_algo_name(algo):
1588     """Return name of public key algorithm
1589
1590     Return the name of the public key algorithm for a given numeric
1591     algorithm id ALGO (cf. RFC4880).
1592
1593     Returns:
1594     algo      - a string
1595
1596     """
1597     return gpgme.gpgme_pubkey_algo_name(algo)
1598
1599
1600 def hash_algo_name(algo):
1601     """Return name of hash algorithm
1602
1603     Return the name of the hash algorithm for a given numeric
1604     algorithm id ALGO (cf. RFC4880).
1605
1606     Returns:
1607     algo      - a string
1608
1609     """
1610     return gpgme.gpgme_hash_algo_name(algo)
1611
1612
1613 def get_protocol_name(proto):
1614     """Get protocol description
1615
1616     Get the string describing protocol PROTO.
1617
1618     Returns:
1619     proto     - a string
1620
1621     """
1622     return gpgme.gpgme_get_protocol_name(proto)
1623
1624
1625 def addrspec_from_uid(uid):
1626     """Return the address spec
1627
1628     Return the addr-spec (cf. RFC2822 section 4.3) from a user id UID.
1629
1630     Returns:
1631     addr_spec - a string
1632
1633     """
1634     return gpgme.gpgme_addrspec_from_uid(uid)
1635
1636
1637 def check_version(version=None):
1638     return gpgme.gpgme_check_version(version)
1639
1640 # check_version also makes sure that several subsystems are properly
1641 # initialized, and it must be run at least once before invoking any
1642 # other function.  We do it here so that the user does not have to do
1643 # it unless she really wants to check for a certain version.
1644 check_version()
1645
1646
1647 def engine_check_version(proto):
1648     try:
1649         errorcheck(gpgme.gpgme_engine_check_version(proto))
1650         return True
1651     except errors.GPGMEError:
1652         return False
1653
1654
1655 def get_engine_info():
1656     ptr = gpgme.new_gpgme_engine_info_t_p()
1657     try:
1658         errorcheck(gpgme.gpgme_get_engine_info(ptr))
1659         info = gpgme.gpgme_engine_info_t_p_value(ptr)
1660     except errors.GPGMEError:
1661         info = None
1662     gpgme.delete_gpgme_engine_info_t_p(ptr)
1663     return info
1664
1665
1666 def set_engine_info(proto, file_name, home_dir=None):
1667     """Changes the default configuration of the crypto engine implementing
1668     the protocol 'proto'. 'file_name' is the file name of
1669     the executable program implementing this protocol. 'home_dir' is the
1670     directory name of the configuration directory (engine's default is
1671     used if omitted)."""
1672     errorcheck(gpgme.gpgme_set_engine_info(proto, file_name, home_dir))
1673
1674
1675 def set_locale(category, value):
1676     """Sets the default locale used by contexts"""
1677     errorcheck(gpgme.gpgme_set_locale(None, category, value))
1678
1679
1680 def wait(hang):
1681     """Wait for asynchronous call on any Context  to finish.
1682     Wait forever if hang is True.
1683
1684     For finished anynch calls it returns a tuple (status, context):
1685         status  - status return by asnynchronous call.
1686         context - context which caused this call to return.
1687
1688     Please read the GPGME manual of more information."""
1689     ptr = gpgme.new_gpgme_error_t_p()
1690     context = gpgme.gpgme_wait(None, ptr, hang)
1691     status = gpgme.gpgme_error_t_p_value(ptr)
1692     gpgme.delete_gpgme_error_t_p(ptr)
1693     if context is None:
1694         errorcheck(status)
1695     else:
1696         context = Context(context)
1697     return (status, context)