From d3a21679cd877f68d9b63e2459e22043dc6b548a Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Fri, 20 Dec 2013 21:19:59 -0800 Subject: [PATCH] Add secret-key decryption to _parse_generic_secret_key_packet The checksum checks will fail with encrypted algorithm-specific key data. This adds handling to decrypt the encrypted section with a new PGPPacket.decrypt_symmetric_encryption stub that still needs to be filled in. From RFC 4880 [1]: With V4 keys, a simpler method is used. All secret MPI values are encrypted in CFB mode, including the MPI bitcount prefix. The two-octet checksum that follows the algorithm-specific portion is the algebraic sum, mod 65536, of the plaintext of all the algorithm- specific octets (including MPI prefix and data). With V3 keys, the checksum is stored in the clear. With V4 keys, the checksum is encrypted like the algorithm-specific data. [1]: http://tools.ietf.org/search/rfc4880#section-5.5.3 --- gpg-migrate.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/gpg-migrate.py b/gpg-migrate.py index 3444982..785f78e 100755 --- a/gpg-migrate.py +++ b/gpg-migrate.py @@ -1,5 +1,6 @@ #!/usr/bin/python +import getpass as _getpass import hashlib as _hashlib import math as _math import re as _re @@ -518,15 +519,20 @@ class PGPPacket (dict): self['symmetric-encryption-algorithm'])) self['initial-vector'] = data[offset: offset + block_size] offset += block_size + ciphertext = data[offset:] + offset += len(ciphertext) + decrypted_data = self.decrypt_symmetric_encryption(data=ciphertext) + else: + decrypted_data = data[offset:key_end] if string_to_key_usage in [0, 255]: key_end = -2 elif string_to_key_usage == 254: key_end = -20 else: key_end = 0 - secret_key = data[offset:key_end] + secret_key = decrypted_data[:key_end] if key_end: - secret_key_checksum = data[key_end:] + secret_key_checksum = decrypted_data[key_end:] if key_end == -2: calculated_checksum = sum(secret_key) % 65536 else: @@ -783,6 +789,9 @@ class PGPPacket (dict): self['public-key-algorithm'])) return b''.join(chunks) + def decrypt_symmetric_encryption(self, data): + raise NotImplementedError('decrypt symmetric encryption') + def packets_from_bytes(data): offset = 0 -- 2.26.2