diff -Nru python-pgpdump-1.3/PKG-INFO python-pgpdump-1.4/PKG-INFO --- python-pgpdump-1.3/PKG-INFO 2012-05-12 03:55:29.000000000 +0000 +++ python-pgpdump-1.4/PKG-INFO 2012-10-22 15:36:42.000000000 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: pgpdump -Version: 1.3 +Version: 1.4 Summary: PGP packet parser library Home-page: https://github.com/toofishes/python-pgpdump Author: Dan McGee diff -Nru python-pgpdump-1.3/README python-pgpdump-1.4/README --- python-pgpdump-1.3/README 2012-03-08 07:12:28.000000000 +0000 +++ python-pgpdump-1.4/README 2012-10-22 15:15:22.000000000 +0000 @@ -9,7 +9,9 @@ * Signature packets * Public key packets +* Secret key packets +* Trust, user ID, and user attribute packets * ASCII-armor decoding and CRC check A single codebase with dependencies on only the standard python library is -compatible across Python 2.7, Python 3.2, and PyPy 1.8. +compatible across Python 2.7, Python 3.2+, and PyPy 1.8+. diff -Nru python-pgpdump-1.3/README.md python-pgpdump-1.4/README.md --- python-pgpdump-1.3/README.md 2012-03-08 07:12:28.000000000 +0000 +++ python-pgpdump-1.4/README.md 2012-10-22 15:15:22.000000000 +0000 @@ -9,7 +9,9 @@ * Signature packets * Public key packets +* Secret key packets +* Trust, user ID, and user attribute packets * ASCII-armor decoding and CRC check A single codebase with dependencies on only the standard python library is -compatible across Python 2.7, Python 3.2, and PyPy 1.8. +compatible across Python 2.7, Python 3.2+, and PyPy 1.8+. diff -Nru python-pgpdump-1.3/debian/changelog python-pgpdump-1.4/debian/changelog --- python-pgpdump-1.3/debian/changelog 2012-10-20 02:28:28.000000000 +0000 +++ python-pgpdump-1.4/debian/changelog 2013-09-13 16:53:54.000000000 +0000 @@ -1,3 +1,9 @@ +python-pgpdump (1.4-1) unstable; urgency=low + + * updated to latest upstream release + + -- Hans-Christoph Steiner Fri, 13 Sep 2013 12:36:03 -0400 + python-pgpdump (1.3-1) unstable; urgency=low * Initial release (Closes: #690900) diff -Nru python-pgpdump-1.3/debian/control python-pgpdump-1.4/debian/control --- python-pgpdump-1.3/debian/control 2012-10-20 02:22:49.000000000 +0000 +++ python-pgpdump-1.4/debian/control 2013-09-13 16:55:02.000000000 +0000 @@ -10,10 +10,10 @@ python3-setuptools X-Python-Version: >= 2.7 X-Python3-Version: >= 3.1 -Standards-Version: 3.9.3 +Standards-Version: 3.9.4 Homepage: https://pypi.python.org/pypi/pgpdump/ -Vcs-Git: git://git.debian.org/collab-maint/python-pgpdump.git -Vcs-Browser: http://git.debian.org/?p=collab-maint/python-pgpdump.git;a=summary +Vcs-Git: git://anonscm.debian.org/collab-maint/python-pgpdump.git +Vcs-Browser: http://anonscm.debian.org/gitweb/?p=collab-maint/python-pgpdump.git;a=summary Package: python-pgpdump Architecture: all @@ -23,14 +23,14 @@ RFC2440 and RFC4880. It is derived from pgpdump, a C program published at: http://www.mew.org/~kazu/proj/pgpdump/ The intent is to support what people actually have to do with PGP packets 95% of the time. This module does not - aim to be a complete PGP parser, as we it currently does not decode every PGP + aim to be a complete PGP parser, as it currently does not decode every PGP packet type. Currently supported things include: . * Signature packets * Public key packets * ASCII-armor decoding and CRC check . - A single codebase with dependencies on only the standard python library is + A single codebase with dependencies on only the standard Python library is compatible across Python 2.7, Python 3.2, and PyPy 1.8. . This is the Python 2 version of the package. @@ -43,14 +43,14 @@ RFC2440 and RFC4880. It is derived from pgpdump, a C program published at: http://www.mew.org/~kazu/proj/pgpdump/ The intent is to support what people actually have to do with PGP packets 95% of the time. This module does not - aim to be a complete PGP parser, as we it currently does not decode every PGP + aim to be a complete PGP parser, as it currently does not decode every PGP packet type. Currently supported things include: . * Signature packets * Public key packets * ASCII-armor decoding and CRC check . - A single codebase with dependencies on only the standard python library is + A single codebase with dependencies on only the standard Python library is compatible across Python 2.7, Python 3.2, and PyPy 1.8. . This is the Python 3 version of the package. diff -Nru python-pgpdump-1.3/debian/watch python-pgpdump-1.4/debian/watch --- python-pgpdump-1.3/debian/watch 1970-01-01 00:00:00.000000000 +0000 +++ python-pgpdump-1.4/debian/watch 2013-09-13 16:27:30.000000000 +0000 @@ -0,0 +1,3 @@ +version=3 +https://github.com/toofishes/python-pgpdump/releases \ +.*/v?(\d\S*)\.(?:tar\.xz|txz|tar\.bz2|tbz2|tar\.gz|tgz) diff -Nru python-pgpdump-1.3/pgpdump/__init__.py python-pgpdump-1.4/pgpdump/__init__.py --- python-pgpdump-1.3/pgpdump/__init__.py 2012-05-12 03:50:42.000000000 +0000 +++ python-pgpdump-1.4/pgpdump/__init__.py 2012-10-22 15:15:22.000000000 +0000 @@ -30,7 +30,7 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -__version__ = "1.3" +__version__ = "1.4" __author__ = "Dan McGee" from .data import AsciiData, BinaryData diff -Nru python-pgpdump-1.3/pgpdump/packet.py python-pgpdump-1.4/pgpdump/packet.py --- python-pgpdump-1.3/pgpdump/packet.py 2012-05-12 03:50:42.000000000 +0000 +++ python-pgpdump-1.4/pgpdump/packet.py 2012-10-22 15:15:22.000000000 +0000 @@ -24,7 +24,7 @@ '''Perform any parsing necessary to populate fields on this packet. This method is called as the last step in __init__(). The base class method is a no-op; subclasses should use this as required.''' - pass + return 0 def __repr__(self): new = "old" @@ -73,6 +73,36 @@ return "Private/Experimental algorithm" return cls.hash_algorithms.get(alg, "Unknown") + sym_algorithms = { + # (Name, IV length) + 0: ("Plaintext or unencrypted", 0), + 1: ("IDEA", 8), + 2: ("Triple-DES", 8), + 3: ("CAST5", 8), + 4: ("Blowfish", 8), + 5: ("Reserved", 8), + 6: ("Reserved", 8), + 7: ("AES with 128-bit key", 16), + 8: ("AES with 192-bit key", 16), + 9: ("AES with 256-bit key", 16), + 10: ("Twofish with 256-bit key", 16), + 11: ("Camellia with 128-bit key", 16), + 12: ("Camellia with 192-bit key", 16), + 13: ("Camellia with 256-bit key", 16), + } + + @classmethod + def _lookup_sym_algorithm(cls, alg): + return cls.sym_algorithms.get(alg, ("Unknown", 0)) + + @classmethod + def lookup_sym_algorithm(cls, alg): + return cls._lookup_sym_algorithm(alg)[0] + + @classmethod + def lookup_sym_algorithm_iv(cls, alg): + return cls._lookup_sym_algorithm(alg)[1] + class SignatureSubpacket(object): '''A signature subpacket containing a type, type name, some flags, and the @@ -216,6 +246,8 @@ raise PgpdumpException("Unsupported signature packet, version %d" % self.sig_version) + return offset + def parse_subpackets(self, outer_offset, outer_length, hashed=False): offset = outer_offset while offset < outer_offset + outer_length: @@ -369,6 +401,8 @@ raise PgpdumpException("Unsupported public key packet, version %d" % self.pubkey_version) + return offset + def parse_key_material(self, offset): if self.raw_pub_algorithm in (1, 2, 3): self.pub_algorithm_type = "rsa" @@ -418,6 +452,161 @@ pass +class SecretKeyPacket(PublicKeyPacket): + def __init__(self, *args, **kwargs): + self.s2k_id = None + self.s2k_type = None + self.s2k_cipher = None + self.s2k_hash = None + self.s2k_iv = None + self.checksum = None + # RSA fields + self.exponent_d = None + self.prime_p = None + self.prime_q = None + self.multiplicative_inverse = None + # DSA and Elgamal + self.exponent_x = None + super(SecretKeyPacket, self).__init__(*args, **kwargs) + + def parse(self): + # parse the public part + offset = PublicKeyPacket.parse(self) + + # parse secret-key packet format from section 5.5.3 + self.s2k_id = self.data[offset] + offset += 1 + + if self.s2k_id == 0: + # plaintext key data + offset = self.parse_private_key_material(offset) + self.checksum = get_int2(self.data, offset) + offset += 2 + elif self.s2k_id in (254, 255): + # encrypted key data + cipher_id = self.data[offset] + offset += 1 + self.s2k_cipher = self.lookup_sym_algorithm(cipher_id) + + # s2k_length is the len of the entire S2K specifier, as per + # section 3.7.1 in RFC 4880 + # we parse the info inside the specifier, but verify the # of + # octects we've parsed matches the expected length of the s2k + offset_before_s2k = offset + + s2k_type_id = self.data[offset] + offset += 1 + name, s2k_length = S2K_TYPES.get(s2k_type_id, ("Unknown", 0)) + self.s2k_type = name + + has_iv = True + if s2k_type_id == 0: + # simple string-to-key + hash_id = self.data[offset] + offset += 1 + self.s2k_hash = self.lookup_hash_algorithm(hash_id) + + elif s2k_type_id == 1: + # salted string-to-key + hash_id = self.data[offset] + offset += 1 + self.s2k_hash = self.lookup_hash_algorithm(hash_id) + # ignore 8 bytes + offset += 8 + + elif s2k_type_id == 2: + # reserved + pass + + elif s2k_type_id == 3: + # iterated and salted + hash_id = self.data[offset] + offset += 1 + self.s2k_hash = self.lookup_hash_algorithm(hash_id) + # ignore 8 bytes + offset += 8 + # ignore count + offset += 1 + # TODO: parse and store count ? + + elif 100 <= s2k_type_id <= 110: + # GnuPG string-to-key + # According to g10/parse-packet.c near line 1832, the 101 packet + # type is a special GnuPG extension. This S2K extension is + # 6 bytes in total: + # + # Octet 0: 101 + # Octet 1: hash algorithm + # Octet 2-4: "GNU" + # Octet 5: mode integer + hash_id = self.data[offset] + offset += 1 + self.s2k_hash = self.lookup_hash_algorithm(hash_id) + + gnu = self.data[offset:offset + 3] + offset += 3 + if gnu != bytearray(b"GNU"): + raise PgpdumpException( + "S2K parsing error: expected 'GNU', got %s" % gnu) + + mode = self.data[offset] + mode += 1000 + offset += 1 + if mode == 1001: + has_iv = False + else: + # TODO implement other modes? + raise PgpdumpException( + "Unsupported GnuPG S2K extension, encountered mode %d" % mode) + else: + raise PgpdumpException( + "Unsupported public key algorithm %d" % s2k_type_id) + + if s2k_length != (offset - offset_before_s2k): + raise PgpdumpException( + "Error parsing string-to-key specifier, mismatched length") + + if has_iv: + s2k_iv_len = self.lookup_sym_algorithm_iv(cipher_id) + self.s2k_iv = self.data[offset:offset + s2k_iv_len] + offset += s2k_iv_len + + # TODO decrypt key data + # TODO parse checksum + return offset + + def parse_private_key_material(self, offset): + if self.raw_pub_algorithm in (1, 2, 3): + self.pub_algorithm_type = "rsa" + # d, p, q, u + self.exponent_d, offset = get_mpi(self.data, offset) + self.prime_p, offset = get_mpi(self.data, offset) + self.prime_q, offset = get_mpi(self.data, offset) + self.multiplicative_inverse, offset = get_mpi(self.data, offset) + elif self.raw_pub_algorithm == 17: + self.pub_algorithm_type = "dsa" + # x + self.exponent_x, offset = get_mpi(self.data, offset) + elif self.raw_pub_algorithm in (16, 20): + self.pub_algorithm_type = "elg" + # x + self.exponent_x, offset = get_mpi(self.data, offset) + elif 100 <= self.raw_pub_algorithm <= 110: + # Private/Experimental algorithms, just move on + pass + else: + raise PgpdumpException("Unsupported public key algorithm %d" % + self.raw_pub_algorithm) + + return offset + + +class SecretSubkeyPacket(SecretKeyPacket): + '''A Secret-Subkey packet (tag 7) has exactly the same format as a + Secret-Key packet, but denotes a subkey.''' + pass + + class UserIDPacket(Packet): '''A User ID packet consists of UTF-8 text that is intended to represent the name and email address of the key holder. By convention, it includes an @@ -439,6 +628,8 @@ if matches.group(2): self.user_email = matches.group(2).strip() + return self.length + def __repr__(self): return "<%s: %r (%r), length %d>" % ( self.__class__.__name__, self.user_name, self.user_email, @@ -454,7 +645,7 @@ def parse(self): offset = sub_offset = sub_len = 0 - while offset + sub_len < len(self.data): + while offset + sub_len < self.length: # each subpacket is [variable length] [subtype] [data] sub_offset, sub_len, sub_part = new_tag_length(self.data, offset) # sub_len includes the subtype single byte, knock that off @@ -479,6 +670,8 @@ else: self.image_format = "unknown" + return self.length + class TrustPacket(Packet): def __init__(self, *args, **kwargs): @@ -490,18 +683,50 @@ integer values into some internal enumeration.''' if self.length == 2: self.trust = get_int2(self.data, 0) + return 2 + return 0 + + +class PublicKeyEncryptedSessionKeyPacket(Packet, AlgoLookup): + def __init__(self, *args, **kwargs): + self.session_key_version = None + self.key_id = None + self.raw_pub_algorithm = None + self.pub_algorithm = None + super(PublicKeyEncryptedSessionKeyPacket, self).__init__( + *args, **kwargs) + + def parse(self): + self.session_key_version = self.data[0] + if self.session_key_version == 3: + self.key_id = get_key_id(self.data, 1) + self.raw_pub_algorithm = self.data[9] + self.pub_algorithm = self.lookup_pub_algorithm(self.raw_pub_algorithm) + else: + raise PgpdumpException( + "Unsupported encrypted session key packet, version %d" % + self.session_key_version) + + # this is hardcoded to work with the only known session key version + return 10 + + def __repr__(self): + return "<%s: 0x%s (%s), length %d>" % ( + self.__class__.__name__, self.key_id, self.pub_algorithm, + self.length) TAG_TYPES = { # (Name, PacketType) tuples 0: ("Reserved", None), - 1: ("Public-Key Encrypted Session Key Packet", None), + 1: ("Public-Key Encrypted Session Key Packet", + PublicKeyEncryptedSessionKeyPacket), 2: ("Signature Packet", SignaturePacket), 3: ("Symmetric-Key Encrypted Session Key Packet", None), 4: ("One-Pass Signature Packet", None), - 5: ("Secret Key Packet", None), + 5: ("Secret Key Packet", SecretKeyPacket), 6: ("Public Key Packet", PublicKeyPacket), - 7: ("Secret Subkey Packet", None), + 7: ("Secret Subkey Packet", SecretSubkeyPacket), 8: ("Compressed Data Packet", None), 9: ("Symmetrically Encrypted Data Packet", None), 10: ("Marker Packet", None), @@ -518,6 +743,15 @@ 63: ("Private", None), } +S2K_TYPES = { + # (Name, Length) + 0: ("Simple S2K", 2), + 1: ("Salted S2K", 10), + 2: ("Reserved value", 0), + 3: ("Iterated and Salted S2K", 11), + 101: ("GnuPG S2K", 6), +} + def new_tag_length(data, start): '''Takes a bytearray of data as input, as well as an offset of where to diff -Nru python-pgpdump-1.3/pgpdump/test.py python-pgpdump-1.4/pgpdump/test.py --- python-pgpdump-1.3/pgpdump/test.py 2012-05-12 03:50:42.000000000 +0000 +++ python-pgpdump-1.4/pgpdump/test.py 2012-10-22 15:15:22.000000000 +0000 @@ -6,7 +6,8 @@ from pgpdump import AsciiData, BinaryData from pgpdump.packet import (TAG_TYPES, SignaturePacket, PublicKeyPacket, - PublicSubkeyPacket, UserIDPacket, old_tag_length, new_tag_length) + PublicSubkeyPacket, UserIDPacket, old_tag_length, new_tag_length, + SecretKeyPacket, SecretSubkeyPacket) from pgpdump.utils import (PgpdumpException, crc24, get_int8, get_mpi, get_key_id, get_int_bytes, same_key) @@ -129,7 +130,7 @@ self.check_sig_packet(sig_packet, 70, 4, 0, 1317069230, b"5C2E46A0F53A76ED", 17, 2) self.assertEqual(2, len(sig_packet.subpackets)) - self.assertEqual(["Signature Creation Time","Issuer"], + self.assertEqual(["Signature Creation Time", "Issuer"], [sp.name for sp in sig_packet.subpackets]) def test_parse_ascii_sig_packet(self): @@ -390,6 +391,34 @@ self.assertEqual(888716292, packet.raw_creation_time) +class EncryptedPacketsTestCase(TestCase, Helper): + def test_parse_sessionkey_elg(self): + '''This file contains a public key and message encrypted with an + ElGamal Encrypt-Only key.''' + asc_data = self.load_data('sessionkey_elg.asc') + data = AsciiData(asc_data) + packets = list(data.packets()) + self.assertEqual(2, len(packets)) + session_key = packets[0] + self.assertEqual(3, session_key.session_key_version) + self.assertEqual(b"B705D3A4C3751D38", session_key.key_id) + self.assertEqual(16, session_key.raw_pub_algorithm) + self.assertEqual("ElGamal Encrypt-Only", session_key.pub_algorithm) + + def test_parse_sessionkey_rsa(self): + '''This file contains a public key and message encrypted with a RSA + Encrypt or Sign key.''' + asc_data = self.load_data('sessionkey_rsa.asc') + data = AsciiData(asc_data) + packets = list(data.packets()) + self.assertEqual(2, len(packets)) + session_key = packets[0] + self.assertEqual(3, session_key.session_key_version) + self.assertEqual(b"1C39A7BD114BFFA5", session_key.key_id) + self.assertEqual(1, session_key.raw_pub_algorithm) + self.assertEqual("RSA Encrypt or Sign", session_key.pub_algorithm) + + class PacketTestCase(TestCase): def test_lookup_type(self): self.assertEqual("Signature Packet", TAG_TYPES[2][0]) @@ -428,5 +457,86 @@ self.assertEqual(expected, new_tag_length(invals, 0)) +class SecretKeyPacketTestCase(TestCase, Helper): + def test_parse_encrypted(self): + rawdata = self.load_data('v4_secret_encrypted.gpg') + data = BinaryData(rawdata) + packets = list(data.packets()) + self.assertEqual(7, len(packets)) + subs_seen = 0 + for packet in packets: + self.assertFalse(packet.new) + + if isinstance(packet, SecretSubkeyPacket): + subs_seen += 1 + if subs_seen == 1: + # elg packet + self.assertEqual("elg", packet.pub_algorithm_type) + self.assertEqual(254, packet.s2k_id) + self.assertEqual("Iterated and Salted S2K", packet.s2k_type) + self.assertEqual( + bytearray(b"\x8d\x89\xbd\xdf\x01\x0e\x22\xcd"), + packet.s2k_iv) + elif subs_seen == 2: + # rsa packet + self.assertEqual("rsa", packet.pub_algorithm_type) + self.assertEqual(254, packet.s2k_id) + self.assertEqual("Iterated and Salted S2K", packet.s2k_type) + self.assertEqual( + bytearray(b"\x09\x97\x6b\xf5\xd4\x28\x41\x1d"), + packet.s2k_iv) + elif isinstance(packet, SecretKeyPacket): + self.assertEqual("dsa", packet.pub_algorithm_type) + self.assertEqual(254, packet.s2k_id) + self.assertEqual("Iterated and Salted S2K", packet.s2k_type) + self.assertEqual("CAST5", packet.s2k_cipher) + self.assertEqual("SHA1", packet.s2k_hash) + self.assertEqual( + bytearray(b"\xc3\x87\xeb\xca\x9b\xce\xbc\x78"), + packet.s2k_iv) + + def test_parse_plain(self): + '''The raw values below were extracted from the C version of pgpdump. + The hex strings it outputs were converted to base 10 by running the + following function over the hex strings: + def to_int(x): + return int(x.replace(' ', ''), 16) + ''' + rawdata = self.load_data('v4_secret_plain.gpg') + data = BinaryData(rawdata) + packets = list(data.packets()) + self.assertEqual(7, len(packets)) + subs_seen = 0 + for packet in packets: + self.assertFalse(packet.new) + + if isinstance(packet, SecretSubkeyPacket): + subs_seen += 1 + if subs_seen == 1: + # elg packet + self.assertEqual("elg", packet.pub_algorithm_type) + self.assertEqual(0, packet.s2k_id) + self.assertEqual(None, packet.s2k_type) + self.assertEqual(None, packet.s2k_iv) + self.assertEqual(245799026332407193298181926223748572866928987611495184689013385965880161244176879821250061522687647728, packet.exponent_x) + elif subs_seen == 2: + # rsa packet + self.assertEqual("rsa", packet.pub_algorithm_type) + self.assertEqual(0, packet.s2k_id) + self.assertEqual(None, packet.s2k_type) + self.assertEqual(None, packet.s2k_iv) + self.assertEqual(107429307998432888320715351604215972074903508478185926034856042440678824041847327442082101397552291647796540657257050768251344941490371163761048934745124363183224819621105784780195398083026664006729876758821509430352212953204518272377415915285011886868211417421097179985188014641310204357388385968166040278287, packet.multiplicative_inverse) + self.assertEqual(139930219416447408374822893460828502304441966752753468842648203646336195082149424690339775194932419616945814365656771053789999508162542355224095838373016952414720809190039261860912609841054241835835137530162417625471114503804567967161522096406622711734972153324109508774000862492521907132111400296639152885151, packet.prime_p) + self.assertEqual(141774976438365791329330227605232641244334061384594969589427240157587195987726021563323880620442249788289724672124037112182500862823754846020398652238714637523098123565121790819658975965315629614215592460191153065569430777288475743983312129144619017542854009503581558744199305796137178366407180728113362644607, packet.prime_q) + self.assertEqual(5830467418164177455383939797360032476940913805978768568081128075462505586965694225559897974113088818228809697270431492119090365699278285350171676334156873270109344274747057694689185206358606371235913423003163252354603704380371252575866102476793736443620998412227609599802054206292004785471167177881398711806191315950196087041018693839148033680564198494910540148825273531803832541184563811332315506727878483469747798396155096313345751606322830230368849084875744911041500024805242117661173352379509490605300753957220916597285056567409410296154792321206401452887335121085203916552891062930596871199021743741984622581173, packet.exponent_d) + elif isinstance(packet, SecretKeyPacket): + self.assertEqual("dsa", packet.pub_algorithm_type) + self.assertEqual(254, packet.s2k_id) + self.assertEqual("GnuPG S2K", packet.s2k_type) + self.assertEqual("CAST5", packet.s2k_cipher) + self.assertEqual("SHA1", packet.s2k_hash) + self.assertEqual(None, packet.s2k_iv) + + if __name__ == '__main__': main() diff -Nru python-pgpdump-1.3/testdata/sessionkey_elg.asc python-pgpdump-1.4/testdata/sessionkey_elg.asc --- python-pgpdump-1.3/testdata/sessionkey_elg.asc 1970-01-01 00:00:00.000000000 +0000 +++ python-pgpdump-1.4/testdata/sessionkey_elg.asc 2012-05-12 14:44:10.000000000 +0000 @@ -0,0 +1,18 @@ +-----BEGIN PGP MESSAGE----- +Version: GnuPG v2.0.19 (GNU/Linux) + +hQIOA7cF06TDdR04EAf/S4Y0EIc+gZpGMMIeRbWKBHgKDlTYSbcZCcRRpWQuhNp3 ++3aAvtufR18rlmMPHKIZXP9TMqA84GIqexHPNufTzoDbPkcNcPk/fiO09gK4GewD +44Gp2iDV5JBAeNMF84KzYSpCTshUNdkfWdLE+XwwxxEFkHvpRGOAz3IUDqARRCXy +wJZ2xEyvu/04VSe8l0vv0HFCsr8an+KxLDpfU9kp4p1Qi6eyEzIAM5HBPRCZzHMg +mOjuRD+Qyp8DoRX62e2kUczH2c1//yBXBqA6DCz1DXG/4XObmzKwD75en40CvmOZ +wSMF8guIV12tC1ZVJP0iK+0rchaKP8AX2MC9YiaQGgf+KUImjjW9Ik6EtBI9A/H5 +1i/EbcflZq8JscH17jkhHB1f7WUaBMQZnLUtPoj/28U3gQb0O9Fc8PD0EBhsenhz +jkIrJXmnMLW9qhdD/GeymIK1GQqVSMBqXXCS0XJINNCW/ZWIgPL9fKtYhAEhA3uj +EILo1vxncOQBIhIKmPctVffB54/hoNakr3hsqZBoGYe3iLipF+W0Tg+/xqjdxVal +szeFjmkbNClX+ou8Opl560ZJen9gujmljLQUbfWfqAfAzpHg5tkbaKY5I+U03GE2 +crcwA5p6D8HObZvOS6GPJWKgXbpAOWX4Q9gFUsQx8K5K1sDk9lhXjtBlvsg+UZgS +m9JKARkukSZKKf1FBHailjJlbpgBt3Uq6QTLJVCqnvwoHZ62+El2Qo4AytcGmKC3 +JqKOwpEwu7k7BD9azZJldRzO94lPxEyuOW20zxQ= +=6Tor +-----END PGP MESSAGE----- diff -Nru python-pgpdump-1.3/testdata/sessionkey_rsa.asc python-pgpdump-1.4/testdata/sessionkey_rsa.asc --- python-pgpdump-1.3/testdata/sessionkey_rsa.asc 1970-01-01 00:00:00.000000000 +0000 +++ python-pgpdump-1.4/testdata/sessionkey_rsa.asc 2012-05-12 14:45:55.000000000 +0000 @@ -0,0 +1,13 @@ +-----BEGIN PGP MESSAGE----- +Version: GnuPG v2.0.19 (GNU/Linux) + +hQEMAxw5p70RS/+lAQf+PKkPn604EcH56EEWdP64SebRVBkIED+Fj1NMLBOu9KCG +keUWYe2LBfxTHK5Con1oR0rbWk3V3TXZMUs8S6l7VJ2mF9dVXftOhhqxU3s2Idjj +QHifQreYLk73FHvONdrIAYIEKcWAyK3s1wZ1WqobRMSXTk/cA7b9YUAQkoctc0Ix +EtgLF/azlR1pc6w97wZI5MKrUnAnCqfbDd9TCHvPE3OhQzceTicHs+q5MLrLd1M3 +zBL2AD+mO6kVs3HvEy/jPd16wAE2SNakeDtJzypcU4PoDy0vpbNOTKnQievRDRCA +58qxnf0r0Yf/R5e6Jgfaf/k64YxZDstnTAigN8I/09JJAcl0dyZmrXLpC4DPTKrN +6UgOjeE2+o6Z6OHvHNMaZSibmZ3vbTQG/C7xl+8mNNZEywcjLSx43zgmWNY8ajH0 +COwqvQVAe7A9kA== +=DQda +-----END PGP MESSAGE----- Binary files /tmp/SQnXgx6dsO/python-pgpdump-1.3/testdata/v4_secret_encrypted.gpg and /tmp/574HGm_0KT/python-pgpdump-1.4/testdata/v4_secret_encrypted.gpg differ Binary files /tmp/SQnXgx6dsO/python-pgpdump-1.3/testdata/v4_secret_plain.gpg and /tmp/574HGm_0KT/python-pgpdump-1.4/testdata/v4_secret_plain.gpg differ