Merge remote-tracking branch 'tomgalloway/develop' into fix/67-hidden-encrypt
commit
09c6a08637
|
@ -804,6 +804,7 @@ class GPGBase(object):
|
||||||
symmetric=False,
|
symmetric=False,
|
||||||
always_trust=True,
|
always_trust=True,
|
||||||
output=None,
|
output=None,
|
||||||
|
hidden_recipients=None,
|
||||||
cipher_algo='AES256',
|
cipher_algo='AES256',
|
||||||
digest_algo='SHA512',
|
digest_algo='SHA512',
|
||||||
compress_algo='ZLIB'):
|
compress_algo='ZLIB'):
|
||||||
|
@ -876,6 +877,10 @@ class GPGBase(object):
|
||||||
>>> decrypted
|
>>> decrypted
|
||||||
'The crow flies at midnight.'
|
'The crow flies at midnight.'
|
||||||
|
|
||||||
|
:param list hidden_recipients: A list of recipients that should
|
||||||
|
have their keyid zero'd out in packet
|
||||||
|
information.
|
||||||
|
|
||||||
:param str cipher_algo: The cipher algorithm to use. To see available
|
:param str cipher_algo: The cipher algorithm to use. To see available
|
||||||
algorithms with your version of GnuPG, do:
|
algorithms with your version of GnuPG, do:
|
||||||
:command:`$ gpg --with-colons --list-config
|
:command:`$ gpg --with-colons --list-config
|
||||||
|
@ -942,21 +947,27 @@ class GPGBase(object):
|
||||||
log.info("Can't accept recipient string: %s"
|
log.info("Can't accept recipient string: %s"
|
||||||
% recp)
|
% recp)
|
||||||
else:
|
else:
|
||||||
args.append('--recipient %s' % str(recp))
|
self._add_recipient_string(args, hidden_recipients, str(recp))
|
||||||
continue
|
continue
|
||||||
## will give unicode in 2.x as '\uXXXX\uXXXX'
|
## will give unicode in 2.x as '\uXXXX\uXXXX'
|
||||||
|
if isinstance(hidden_recipients, (list, tuple)):
|
||||||
|
if [s for s in hidden_recipients if recp in str(s)]:
|
||||||
|
args.append('--hidden-recipient %r' % recp)
|
||||||
|
else:
|
||||||
|
args.append('--recipient %r' % recp)
|
||||||
|
else:
|
||||||
args.append('--recipient %r' % recp)
|
args.append('--recipient %r' % recp)
|
||||||
continue
|
continue
|
||||||
if isinstance(recp, str):
|
if isinstance(recp, str):
|
||||||
args.append('--recipient %s' % recp)
|
self._add_recipient_string(args, hidden_recipients, recp)
|
||||||
|
|
||||||
elif (not _util._py3k) and isinstance(recp, basestring):
|
elif (not _util._py3k) and isinstance(recp, basestring):
|
||||||
for recp in recipients.split('\x20'):
|
for recp in recipients.split('\x20'):
|
||||||
args.append('--recipient %s' % recp)
|
self._add_recipient_string(args, hidden_recipients, recp)
|
||||||
|
|
||||||
elif _util._py3k and isinstance(recp, str):
|
elif _util._py3k and isinstance(recp, str):
|
||||||
for recp in recipients.split(' '):
|
for recp in recipients.split(' '):
|
||||||
args.append('--recipient %s' % recp)
|
self._add_recipient_string(args, hidden_recipients, recp)
|
||||||
## ...and now that we've proven py3k is better...
|
## ...and now that we've proven py3k is better...
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
@ -978,3 +989,12 @@ class GPGBase(object):
|
||||||
log.info("Encrypted output written successfully.")
|
log.info("Encrypted output written successfully.")
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def _add_recipient_string(self, args, hidden_recipients, recipient):
|
||||||
|
if isinstance(hidden_recipients, (list, tuple)):
|
||||||
|
if [s for s in hidden_recipients if recipient in str(s)]:
|
||||||
|
args.append('--hidden-recipient %s' % recipient)
|
||||||
|
else:
|
||||||
|
args.append('--recipient %s' % recipient)
|
||||||
|
else:
|
||||||
|
args.append('--recipient %s' % recipient)
|
|
@ -1512,6 +1512,8 @@ class ListPackets(object):
|
||||||
self.need_passphrase_sym = None
|
self.need_passphrase_sym = None
|
||||||
#: The keyid and uid which this data is encrypted to.
|
#: The keyid and uid which this data is encrypted to.
|
||||||
self.userid_hint = None
|
self.userid_hint = None
|
||||||
|
#: A list of keyid's that the message has been encrypted to.
|
||||||
|
self.key = []
|
||||||
|
|
||||||
def _handle_status(self, key, value):
|
def _handle_status(self, key, value):
|
||||||
"""Parse a status code from the attached GnuPG process.
|
"""Parse a status code from the attached GnuPG process.
|
||||||
|
@ -1521,9 +1523,8 @@ class ListPackets(object):
|
||||||
if key == 'NODATA':
|
if key == 'NODATA':
|
||||||
self.status = nodata(value)
|
self.status = nodata(value)
|
||||||
elif key == 'ENC_TO':
|
elif key == 'ENC_TO':
|
||||||
# This will only capture keys in our keyring. In the future we
|
key_to_add, _, _ = value.split()
|
||||||
# may want to include multiple unknown keys in this list.
|
self.key.append(key_to_add)
|
||||||
self.key, _, _ = value.split()
|
|
||||||
elif key == 'NEED_PASSPHRASE':
|
elif key == 'NEED_PASSPHRASE':
|
||||||
self.need_passphrase = True
|
self.need_passphrase = True
|
||||||
elif key == 'NEED_PASSPHRASE_SYM':
|
elif key == 'NEED_PASSPHRASE_SYM':
|
||||||
|
|
|
@ -885,6 +885,41 @@ authentication."""
|
||||||
|
|
||||||
self.assertEqual(message, decrypted)
|
self.assertEqual(message, decrypted)
|
||||||
|
|
||||||
|
def test_encryption_one_hidden_recipient_one_not(self):
|
||||||
|
"""Test to ensure hidden recipient isn't detailed in packet info"""
|
||||||
|
|
||||||
|
alice = open(os.path.join(_files, 'test_key_1.pub'))
|
||||||
|
alice_pub = alice.read()
|
||||||
|
alice_public = self.gpg.import_keys(alice_pub)
|
||||||
|
res = alice_public.results[-1:][0]
|
||||||
|
alice_pfpr = str(res['fingerprint'])
|
||||||
|
alice.close()
|
||||||
|
|
||||||
|
bob = open(os.path.join(_files, 'test_key_2.pub'))
|
||||||
|
bob_pub = bob.read()
|
||||||
|
bob_public = self.gpg.import_keys(bob_pub)
|
||||||
|
res = bob_public.results[-1:][0]
|
||||||
|
bob_pfpr = str(res['fingerprint'])
|
||||||
|
bob.close()
|
||||||
|
|
||||||
|
message = """
|
||||||
|
In 2010 Riggio and Sicari presented a practical application of homomorphic
|
||||||
|
encryption to a hybrid wireless sensor/mesh network. The system enables
|
||||||
|
transparent multi-hop wireless backhauls that are able to perform statistical
|
||||||
|
analysis of different kinds of data (temperature, humidity, etc.) coming from
|
||||||
|
a WSN while ensuring both end-to-end encryption and hop-by-hop
|
||||||
|
authentication."""
|
||||||
|
enc = self.gpg.encrypt(message, alice_pfpr, bob_pfpr, hidden_recipients=[alice_pfpr])
|
||||||
|
encrypted = str(enc)
|
||||||
|
log.debug("keyid = %s"
|
||||||
|
% alice_pfpr)
|
||||||
|
|
||||||
|
self.assertNotEquals(message, encrypted)
|
||||||
|
## We expect Alice's key to be hidden (returned as zero's) and Bob's
|
||||||
|
## key to be there.
|
||||||
|
expected_values = ["0000000000000000", "E0ED97345F2973D6"]
|
||||||
|
self.assertEquals(expected_values, self.gpg.list_packets(encrypted).key)
|
||||||
|
|
||||||
def test_encryption_decryption_multi_recipient(self):
|
def test_encryption_decryption_multi_recipient(self):
|
||||||
"""Test decryption of an encrypted string for multiple users"""
|
"""Test decryption of an encrypted string for multiple users"""
|
||||||
|
|
||||||
|
@ -1075,6 +1110,7 @@ suites = { 'parsers': set(['test_parsers_fix_unsafe',
|
||||||
'test_encryption_alt_encoding',
|
'test_encryption_alt_encoding',
|
||||||
'test_encryption_multi_recipient',
|
'test_encryption_multi_recipient',
|
||||||
'test_encryption_decryption_multi_recipient',
|
'test_encryption_decryption_multi_recipient',
|
||||||
|
'test_encryption_one_hidden_recipient_one_not',
|
||||||
'test_decryption',
|
'test_decryption',
|
||||||
'test_symmetric_encryption_and_decryption',
|
'test_symmetric_encryption_and_decryption',
|
||||||
'test_file_encryption_and_decryption',
|
'test_file_encryption_and_decryption',
|
||||||
|
|
Loading…
Reference in New Issue