Last active
November 16, 2017 21:07
-
-
Save Commod0re/801256701bc71f0251de2b708365e61c to your computer and use it in GitHub Desktop.
inspect PGP packets in PGPy 0.4.x
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# this is a hackish way to inspect the packets in a PGP object with PGPy 0.4.x | |
# in the future listing packets directly and determining what fields are useful should be part of the API | |
# this example prints a few packet types in close to the same format as gpg --list-packets | |
import sys | |
from pgpy.types import Armorable | |
from pgpy.packet import Packet | |
from pgpy.constants import PacketTag | |
def pgp_packets(text): | |
unarmored = Armorable.ascii_unarmor(text) | |
data = unarmored['body'] | |
while data: | |
pkt = Packet(data) | |
yield pkt | |
if __name__ == '__main__': | |
for fn in sys.argv[1:]: | |
with open(fn) as f: | |
text = f.read() | |
offset = 0 | |
for packet in pgp_packets(text): | |
# if you want to just print the repr for the packet class: | |
# print(packet) | |
# otherwise, details can be gathered and printed by inspecting packet | |
# packet header details (these are common to all packet types) | |
hdr = {} | |
hdr['off'] = offset | |
hdr['ctb'] = packet.header.__bytes__()[0], | |
hdr['tag'] = packet.header.tag, | |
hdr['hlen'] = len(packet.header) | |
hdr['plen'] = len(packet) - hdr['hlen'] | |
hdr['lfmt'] = "new-ctb" if packet.header._lenfmt else "" | |
print("# off={off:} ctb={ctb:02x} tag={tag:} hlen={hlen:} plen={plen:} {lfmt:}".format_map(hdr)) | |
# increment offset for the next packet | |
offset += hdr['plen'] + hdr['hlen'] | |
# interpreting individual packets depends on each packet, here are a couple to get you started | |
# check pgpy/packet/packets.py for the relevant properties in order to add more, or inspect them with dir() or tab completion in ipython | |
if packet.header.tag in {PacketTag.PublicKey, PacketTag.PublicSubKey}: | |
# private key packets have these fields, plus a few more | |
print(":public {} packet:".format("sub key" if packet.header.tag == PacketTag.PublicSubKey else "key")) | |
ver = packet.header.version | |
algo = packet.pkalg | |
created = packet.created | |
# "expires" depends on signatures that follow and this example script isn't smart enough for that currently | |
print(" version {ver:}, algo {algo:}, created {created:}".format(ver=ver, algo=algo, created=created)) | |
for i, field in enumerate(packet.keymaterial.__pubfields__): | |
print(" pkey[{}]: [{} bits]".format(i, getattr(packet.keymaterial, field).bit_length())) | |
print(" keyid: {}".format(packet.fingerprint.keyid)) | |
if packet.header.tag == PacketTag.UserID: | |
# as we work on the packet API this pre-formatting step should become unnecessary | |
uid = packet.name | |
if packet.comment: | |
uid = '{} ({})'.format(uid, uid.comment) | |
if packet.email: | |
uid = '{} <{}>'.format(uid, uid.email) | |
print(':user ID packet: "{}"'.format(uid)) | |
if packet.header.tag == PacketTag.UserAttribute: | |
print(":attribute packet: [{} image of size {}]".format(packet.image.iencoding.name, len(packet.image.image))) | |
# TODO: add more packet types here |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
For a key that is already loaded: