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