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