python bindings: export secret keys

* The holy grail: a function to export secret keys.
* GPGME will still invoke pinentry and gpg-agent as usual to authorise
  the export.
* Mostly similar to the two previous export functions for public keys
  except that it will return None if the result had a length of zero
  bytes.  Meaning that the difference between the specified pattern
  (if any) not matching available keys and an incorrect passphrase is
  not able to be determined from this function (or the underlying one
  for that matter).

Signed-off-by: Ben McGinnes <ben@adversary.org>
This commit is contained in:
Ben McGinnes 2018-06-27 19:16:29 +10:00
parent 870c317120
commit 14cbbb3d70

View File

@ -611,7 +611,7 @@ class Context(GpgmeWrapper):
Raises: Raises:
GPGMEError -- as signaled by the underlying library. GPGMEError -- as signaled by the underlying library.
""" """
data = Data() data = Data()
mode = gpgme.GPGME_EXPORT_MODE_MINIMAL mode = gpgme.GPGME_EXPORT_MODE_MINIMAL
try: try:
@ -623,6 +623,47 @@ class Context(GpgmeWrapper):
return result return result
def key_export_secret(self, pattern=None):
"""Export secret keys.
Exports secret keys matching the pattern specified. If no
pattern is specified then exports or attempts to export all
available secret keys.
IMPORTANT: Each secret key to be exported will prompt for its
passphrase via an invocation of pinentry and gpg-agent. If the
passphrase is not entered or does not match then no data will be
exported. This is the same result as when specifying a pattern
that is not matched by the available keys.
Keyword arguments:
pattern -- return keys matching pattern (default: all keys)
Returns:
-- On success a key block containing one or more OpenPGP
secret keys in either ASCII armoured or binary format
as determined by the Context().
-- On failure while not raising an exception, returns None.
Raises:
GPGMEError -- as signaled by the underlying library.
"""
data = Data()
mode = gpgme.GPGME_EXPORT_MODE_SECRET
try:
self.op_export(pattern, mode, data)
data.seek(0, os.SEEK_SET)
sk_result = data.read()
except GPGMEError as e:
sk_result = e
if len(sk_result) > 0:
result = sk_result
else:
result = None
return result
def keylist(self, pattern=None, secret=False, def keylist(self, pattern=None, secret=False,
mode=constants.keylist.mode.LOCAL, mode=constants.keylist.mode.LOCAL,
source=None): source=None):