GPG.encrypt_file()→GPGBase.encrypt() and fix doctests and documentation.

testing/mmn/mktime_takes_localtime_not_gmtime
Isis Lovecruft 2013-06-04 01:42:07 +00:00
parent d75800a7e0
commit 295d98fbdc
No known key found for this signature in database
GPG Key ID: A3ADB67A2CDB8B35
2 changed files with 220 additions and 116 deletions

View File

@ -582,3 +582,160 @@ class GPGBase(object):
writer = None writer = None
self._collect_output(proc, result, writer, proc.stdin) self._collect_output(proc, result, writer, proc.stdin)
return result return result
def _encrypt(self, data, recipients,
default_key=None,
passphrase=None,
armor=True,
encrypt=True,
symmetric=False,
always_trust=True,
output=None,
cipher_algo='AES256',
digest_algo='SHA512',
compress_algo='ZLIB'):
"""Encrypt the message read from the file-like object ``data``.
:param str data: The file or bytestream to encrypt.
:param str recipients: The recipients to encrypt to. Recipients must
be specified keyID/fingerprint. Care should be taken in Python2.x
to make sure that the given fingerprint is in fact a string and
not a unicode object.
:param str default_key: The keyID/fingerprint of the key to use for
signing. If given, ``data`` will be encrypted and signed.
:param str passphrase: If given, and ``default_key`` is also given,
use this passphrase to unlock the secret portion of the
``default_key`` to sign the encrypted ``data``. Otherwise, if
``default_key`` is not given, but ``symmetric=True``, then use
this passphrase as the passphrase for symmetric
encryption. Signing and symmetric encryption should *not* be
combined when sending the ``data`` to other recipients, else the
passphrase to the secret key would be shared with them.
:param bool armor: If True, ascii armor the output; otherwise, the
output will be in binary format. (Default: True)
:param bool encrypt: If True, encrypt the ``data`` using the
``recipients`` public keys. (Default: True)
:param bool symmetric: If True, encrypt the ``data`` to ``recipients``
using a symmetric key. See the ``passphrase`` parameter. Symmetric
encryption and public key encryption can be used simultaneously,
and will result in a ciphertext which is decryptable with either
the symmetric ``passphrase`` or one of the corresponding private
keys.
:param bool always_trust: If True, ignore trust warnings on recipient
keys. If False, display trust warnings. (default: True)
:param str output: The output file to write to. If not specified, the
encrypted output is returned, and thus should be stored as an
object in Python. For example:
>>> import shutil
>>> import gnupg
>>> if os.path.exists("doctests"):
... shutil.rmtree("doctests")
>>> gpg = gnupg.GPG(homedir="doctests")
>>> key_settings = gpg.gen_key_input(key_type='RSA',
... key_length=1024,
... key_usage='ESCA',
... passphrase='foo')
>>> key = gpg.gen_key(key_settings)
>>> message = "The crow flies at midnight."
>>> encrypted = str(gpg.encrypt(message, key.printprint))
>>> assert encrypted != message
>>> assert not encrypted.isspace()
>>> decrypted = str(gpg.decrypt(encrypted))
>>> assert not decrypted.isspace()
>>> decrypted
'The crow flies at midnight.'
:param str cipher_algo: The cipher algorithm to use. To see available
algorithms with your version of GnuPG, do:
``$ gpg --with-colons --list-config ciphername``.
The default ``cipher_algo``, if unspecified, is ``'AES256'``.
:param str digest_algo: The hash digest to use. Again, to see which
hashes your GnuPG is capable of using, do:
``$ gpg --with-colons --list-config digestname``.
The default, if unspecified, is ``'SHA512'``.
:param str compress_algo: The compression algorithm to use. Can be one
of ``'ZLIB'``, ``'BZIP2'``, ``'ZIP'``, or ``'Uncompressed'``.
"""
args = []
if output:
if getattr(output, 'fileno', None) is not None:
## avoid overwrite confirmation message
if getattr(output, 'name', None) is None:
if os.path.exists(output):
os.remove(output)
args.append('--output %s' % output)
else:
if os.path.exists(output.name):
os.remove(output.name)
args.append('--output %s' % output.name)
if armor: args.append('--armor')
if always_trust: args.append('--always-trust')
if cipher_algo: args.append('--cipher-algo %s' % cipher_algo)
if compress_algo: args.append('--compress-algo %s' % compress_algo)
if default_key:
args.append('--sign')
args.append('--default-key %s' % default_key)
if digest_algo:
args.append('--digest-algo %s' % digest_algo)
## both can be used at the same time for an encrypted file which
## is decryptable with a passphrase or secretkey.
if symmetric: args.append('--symmetric')
if encrypt: args.append('--encrypt')
if len(recipients) >= 1:
log.debug("GPG.encrypt() called for recipients '%s' with type '%s'"
% (recipients, type(recipients)))
if isinstance(recipients, (list, tuple)):
for recp in recipients:
if not _util._py3k:
if isinstance(recp, unicode):
try:
assert _parsers._is_hex(str(recp))
except AssertionError:
log.info("Can't accept recipient string: %s"
% recp)
else:
args.append('--recipient %s' % str(recp))
continue
## will give unicode in 2.x as '\uXXXX\uXXXX'
args.append('--recipient %r' % recp)
continue
if isinstance(recp, str):
args.append('--recipient %s' % recp)
elif (not _util._py3k) and isinstance(recp, basestring):
for recp in recipients.split('\x20'):
args.append('--recipient %s' % recp)
elif _util._py3k and isinstance(recp, str):
for recp in recipients.split(' '):
args.append('--recipient %s' % recp)
## ...and now that we've proven py3k is better...
else:
log.debug("Don't know what to do with recipients: '%s'"
% recipients)
result = self._result_map['crypt'](self)
log.debug("Got data '%s' with type '%s'."
% (data, type(data)))
self._handle_io(args, data, result,
passphrase=passphrase, binary=True)
log.debug('GPG.encrypt_file(): Result: %r', result.data)
return result

View File

@ -831,135 +831,82 @@ generate keys. Please see
return out return out
def encrypt_file(self, filename, recipients,
default_key=None,
passphrase=None,
armor=True,
encrypt=True,
symmetric=False,
always_trust=True,
output=None,
cipher_algo='AES256',
digest_algo='SHA512',
compress_algo='ZLIB'):
"""Encrypt the message read from the file-like object ``filename``.
:param str filename: The file or bytestream to encrypt.
:param str recipients: The recipients to encrypt to. Recipients must
be specified keyID/fingerprint. Care should be
taken in Python2.x to make sure that the given
fingerprint is in fact a string and not a
unicode object.
:param str default_key: The keyID/fingerprint of the key to use for
signing. If given, ``filename`` will be
encrypted and signed.
:param bool always_trust: If True, ignore trust warnings on recipient
keys. If False, display trust warnings.
(default: True)
:param str passphrase: If True, use this passphrase to unlock the
secret portion of the ``default_key`` for
signing.
:param bool armor: If True, ascii armor the output; otherwise, the
output will be in binary format. (default: True)
:param str output: The output file to write to. If not specified, the
encrypted output is returned, and thus should be
stored as an object in Python. For example:
"""
args = []
if output:
if getattr(output, 'fileno', None) is not None:
## avoid overwrite confirmation message
if getattr(output, 'name', None) is None:
if os.path.exists(output):
os.remove(output)
args.append('--output %s' % output)
else:
if os.path.exists(output.name):
os.remove(output.name)
args.append('--output %s' % output.name)
if armor: args.append('--armor')
if always_trust: args.append('--always-trust')
if cipher_algo: args.append('--cipher-algo %s' % cipher_algo)
if compress_algo: args.append('--compress-algo %s' % compress_algo)
if default_key:
args.append('--sign')
args.append('--default-key %s' % default_key)
if digest_algo:
args.append('--digest-algo %s' % digest_algo)
## both can be used at the same time for an encrypted file which
## is decryptable with a passphrase or secretkey.
if symmetric: args.append('--symmetric')
if encrypt: args.append('--encrypt')
if len(recipients) >= 1:
log.debug("GPG.encrypt() called for recipients '%s' with type '%s'"
% (recipients, type(recipients)))
if isinstance(recipients, (list, tuple)):
for recp in recipients:
if not _util._py3k:
if isinstance(recp, unicode):
try:
assert _parsers._is_hex(str(recp))
except AssertionError:
log.info("Can't accept recipient string: %s"
% recp)
else:
args.append('--recipient %s' % str(recp))
continue
## will give unicode in 2.x as '\uXXXX\uXXXX'
args.append('--recipient %r' % recp)
continue
if isinstance(recp, str):
args.append('--recipient %s' % recp)
elif (not _util._py3k) and isinstance(recp, basestring):
for recp in recipients.split('\x20'):
args.append('--recipient %s' % recp)
elif _util._py3k and isinstance(recp, str):
for recp in recipients.split(' '):
args.append('--recipient %s' % recp)
## ...and now that we've proven py3k is better...
else:
log.debug("Don't know what to do with recipients: '%s'"
% recipients)
result = self._result_map['crypt'](self)
log.debug("Got filename '%s' with type '%s'."
% (filename, type(filename)))
self._handle_io(args, filename, result,
passphrase=passphrase, binary=True)
log.debug('GPG.encrypt_file(): Result: %r', result.data)
return result
def encrypt(self, data, *recipients, **kwargs): def encrypt(self, data, *recipients, **kwargs):
"""Encrypt the message contained in ``data`` to ``recipients``. """Encrypt the message contained in ``data`` to ``recipients``.
:param str data: The file or bytestream to encrypt.
:param str recipients: The recipients to encrypt to. Recipients must
be specified keyID/fingerprint. Care should be taken in Python2.x
to make sure that the given fingerprint is in fact a string and
not a unicode object.
:param str default_key: The keyID/fingerprint of the key to use for
signing. If given, ``data`` will be encrypted and signed.
:param str passphrase: If given, and ``default_key`` is also given,
use this passphrase to unlock the secret portion of the
``default_key`` to sign the encrypted ``data``. Otherwise, if
``default_key`` is not given, but ``symmetric=True``, then use
this passphrase as the passphrase for symmetric
encryption. Signing and symmetric encryption should *not* be
combined when sending the ``data`` to other recipients, else the
passphrase to the secret key would be shared with them.
:param bool armor: If True, ascii armor the output; otherwise, the
output will be in binary format. (Default: True)
:param bool encrypt: If True, encrypt the ``data`` using the
``recipients`` public keys. (Default: True)
:param bool symmetric: If True, encrypt the ``data`` to ``recipients``
using a symmetric key. See the ``passphrase`` parameter. Symmetric
encryption and public key encryption can be used simultaneously,
and will result in a ciphertext which is decryptable with either
the symmetric ``passphrase`` or one of the corresponding private
keys.
:param bool always_trust: If True, ignore trust warnings on recipient
keys. If False, display trust warnings. (default: True)
:param str output: The output file to write to. If not specified, the
encrypted output is returned, and thus should be stored as an
object in Python. For example:
>>> import shutil >>> import shutil
>>> import gnupg
>>> if os.path.exists("doctests"): >>> if os.path.exists("doctests"):
... shutil.rmtree("doctests") ... shutil.rmtree("doctests")
>>> gpg = GPG(homedir="doctests") >>> gpg = gnupg.GPG(homedir="doctests")
>>> key_settings = gpg.gen_key_input(key_type='RSA', >>> key_settings = gpg.gen_key_input(key_type='RSA',
... key_length=1024, ... key_length=1024,
... key_usage='ESCA', ... key_usage='ESCA',
... passphrase='foo') ... passphrase='foo')
>>> key = gpg.gen_key(key_settings) >>> key = gpg.gen_key(key_settings)
>>> encrypted = gpg.encrypt("sekrit", key.printprint) >>> message = "The crow flies at midnight."
>>> message = str(encrypted) >>> encrypted = str(gpg.encrypt(message, key.printprint))
>>> assert message != 'sekrit' >>> assert encrypted != message
>>> decrypted = gpg.decrypt(message) >>> assert not encrypted.isspace()
>>> assert decrypted >>> decrypted = str(gpg.decrypt(encrypted))
>>> str(decrypted) >>> assert not decrypted.isspace()
'sekrit' >>> decrypted
'The crow flies at midnight.'
:param str cipher_algo: The cipher algorithm to use. To see available
algorithms with your version of GnuPG, do:
``$ gpg --with-colons --list-config ciphername``.
The default ``cipher_algo``, if unspecified, is ``'AES256'``.
:param str digest_algo: The hash digest to use. Again, to see which
hashes your GnuPG is capable of using, do:
``$ gpg --with-colons --list-config digestname``.
The default, if unspecified, is ``'SHA512'``.
:param str compress_algo: The compression algorithm to use. Can be one
of ``'ZLIB'``, ``'BZIP2'``, ``'ZIP'``, or ``'Uncompressed'``.
""" """
stream = _make_binary_stream(data, self._encoding) stream = _make_binary_stream(data, self._encoding)
result = self.encrypt_file(stream, recipients, **kwargs) result = self._encrypt(stream, recipients, **kwargs)
stream.close() stream.close()
return result return result