Skip to content
Browse files

Support version 3 ElGamal public keys

We're entering territory modern verisons of GPG don't even support. The
"correct" values are determined from those that the keyserver is telling
us, and a test case is added using those values from a rather old key.

Signed-off-by: Dan McGee <dpmcgee@gmail.com>
  • Loading branch information...
1 parent 7a63495 commit cae58be10b31df9f2fcd6ed4c15fab019686a883 @toofishes committed Apr 9, 2012
Showing with 62 additions and 7 deletions.
  1. +1 −0 MANIFEST.in
  2. +16 −7 pgpdump/packet.py
  3. +28 −0 pgpdump/test.py
  4. +17 −0 testdata/v3elgpk.asc
View
1 MANIFEST.in
@@ -5,4 +5,5 @@ include testdata/dan.gpg
include testdata/junio.gpg
include testdata/linus.asc
include testdata/linus.gpg
+include testdata/v3elgpk.asc
include testdata/v3pubkeys.gpg
View
23 pgpdump/packet.py
@@ -329,15 +329,24 @@ def parse(self):
offset += 1
offset = self.parse_key_material(offset)
+ md5 = hashlib.md5()
# Key type must be RSA for v2 and v3 public keys
- if self.pub_algorithm_type != "rsa":
+ if self.pub_algorithm_type == "rsa":
+ key_id = ('%X' % self.modulus)[-8:].zfill(8)
+ self.key_id = key_id.encode('ascii')
+ md5.update(get_int_bytes(self.modulus))
+ md5.update(get_int_bytes(self.exponent))
+ elif self.pub_algorithm_type == "elg":
+ # Of course, there are ELG keys in the wild too. This formula
+ # for calculating key_id and fingerprint is derived from an old
+ # key and there is a test case based on it.
+ key_id = ('%X' % self.prime)[-8:].zfill(8)
+ self.key_id = key_id.encode('ascii')
+ md5.update(get_int_bytes(self.prime))
+ md5.update(get_int_bytes(self.group_gen))
+ else:
raise PgpdumpException("Invalid non-RSA v%d public key" %
self.pubkey_version)
-
- self.key_id = ('%X' % self.modulus)[-8:].zfill(8).encode('ascii')
- md5 = hashlib.md5()
- md5.update(get_int_bytes(self.modulus))
- md5.update(get_int_bytes(self.exponent))
self.fingerprint = md5.hexdigest().upper().encode('ascii')
elif self.pubkey_version == 4:
sha1 = hashlib.sha1()
@@ -374,7 +383,7 @@ def parse_key_material(self, offset):
self.group_gen, offset = get_mpi(self.data, offset)
self.key_value, offset = get_mpi(self.data, offset)
elif self.raw_pub_algorithm in (16, 20):
- self.pub_algorithm_type = "elgamal"
+ self.pub_algorithm_type = "elg"
# p, g, y
self.prime, offset = get_mpi(self.data, offset)
self.group_gen, offset = get_mpi(self.data, offset)
View
28 pgpdump/test.py
@@ -361,6 +361,34 @@ def test_parse_v3_pubkeys(self):
self.assertEqual(b"48A4F9F891F093019BC7FC532A3C5692",
packet.fingerprint)
+ def test_parse_v3_elgamal_pk(self):
+ '''Two older version 3 public keys.'''
+ rawdata = self.load_data('v3elgpk.asc')
+ data = AsciiData(rawdata)
+ packets = list(data.packets())
+ self.assertEqual(3, len(packets))
+
+ packet = packets[0]
+ self.assertTrue(isinstance(packet, PublicKeyPacket))
+ self.assertEqual(16, packet.raw_pub_algorithm)
+ self.assertEqual("elg", packet.pub_algorithm_type)
+ self.assertEqual(888716291, packet.raw_creation_time)
+ self.assertIsNone(packet.expiration_time)
+ self.assertIsNone(packet.modulus)
+ self.assertIsNone(packet.exponent)
+ self.assertIsNotNone(packet.prime)
+ self.assertIsNotNone(packet.group_gen)
+ self.assertEqual(b"FF570A03", packet.key_id)
+ self.assertEqual(b"7C4529FB11669ACA567BD53972000594",
+ packet.fingerprint)
+
+ self.assertTrue(isinstance(packets[1], UserIDPacket))
+
+ packet = packets[2]
+ self.assertTrue(isinstance(packet, SignaturePacket))
+ self.assertEqual(16, packet.raw_pub_algorithm)
+ self.assertEqual(888716292, packet.raw_creation_time)
+
class PacketTestCase(TestCase):
def test_lookup_type(self):
View
17 testdata/v3elgpk.asc
@@ -0,0 +1,17 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: SKS 1.1.0
+
+mQEPAzT4vAMAABAEAJIlqDQYvqIEvx3jnxgGmBaseV6Ly/OXNZeO352ymcnhCuCD8pwZmXOw
+LTVpf7UIoQ51j6XUcN6QZSu6QuKG13NH2TJjyOcI4mkwlaGK+NYKo+YEIKlChB3dqFiP1OYa
+ZU4T3hsvZyTSOo7ieug9FvF05wiMByRYTtZjw9z/VwoDAAMFA/96ojAJ71ePXWieIkuIIBrj
+LdFOQ9uOisSEACoM/UT1+vhJb1Fo8/s8xESGoN2jR5DjAn7RbDqv1ryFCaP7J/Qidcf8X1x8
+yJb5ELbvI+jjNCGAMcPU9tVcE1IyoMEptwSqIuvNFdOq0puSnRdrzRLJJZLvA8fJ7V3Cxl+j
+It71brQ+V2ltIFZhbmRlcHV0dGUgKG1pZyBsaW51eCAyLjAuMjkpIDx3dmRwdXR0ZUByZXB0
+aWxlLnJ1Zy5hYy5iZT6JARcDBRM0+LwEXFt+e5KvZo8QA4tDA/9fK8HynDW9/U4a0WT9rJbO
+Y0p7QMRdjJOVu44jkhvpc7VLR2OJ0ETlC98WDz688J8Rspz5LeBvxILuYfXkjOTSnLaqZTWY
+lykDNPQJmetdanCFoDtutfbmhOOuNgd/bHcjlYuKPgE6AXkFnoL9F4ScCG7sjesaLeplqAjK
+AnIUvgP+LHiYpq2Apo2zi2D3K1H3ZPN4qubONK7A+otntSGazj0ks/DAQs0ua78f73If7B3v
+W+jjnxwhp8+c5hqrlKSurdXZ91wAd7V8gUCFIC9pUbZ8UodECxBmOwARnzRfI5yDuGA5vlMu
+8LY/SG5mEsxk5YL9sa3xuCX89oHP51vQwDs=
+=pG5J
+-----END PGP PUBLIC KEY BLOCK-----

0 comments on commit cae58be

Please sign in to comment.
Something went wrong with that request. Please try again.