Skip to content

Commit

Permalink
Add gpg.export_pubkeys function
Browse files Browse the repository at this point in the history
Add convenience function to export multiple public keys from a
gpg keyring into an sslib dict format at once and tests.

Note: Uses the new pseudo-standard docstring style suggested in
secure-systems-lab/code-style-guidelines#20. All new interface
functions should use that style (existing docstrings will be
converted in separate PRs).
  • Loading branch information
lukpueh committed Sep 30, 2020
1 parent 94d83b9 commit 42171a2
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 2 deletions.
26 changes: 26 additions & 0 deletions securesystemslib/gpg/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,3 +299,29 @@ def export_pubkey(keyid, homedir=None):
key_bundle = securesystemslib.gpg.common.get_pubkey_bundle(key_packet, keyid)

return key_bundle


def export_pubkeys(keyids, homedir=None):
"""Export multiple public keys from a GnuPG keyring.
Arguments:
keyid: A list of OpenPGP keyids in KEYID_SCHEMA format.
homedir (optional): A path to the GnuPG home directory. If not set the
default GnuPG home directory is used.
Raises:
TypeError: Keyids is not iterable.
See 'export_pubkey' for other exceptions.
Returns:
A dict with OpenPGP keyids for dict keys and keys in GPG_PUBKEY_SCHEMA
format for values.
"""
public_key_dict = {}
for gpg_keyid in keyids:
public_key = export_pubkey(gpg_keyid, homedir=homedir)
keyid = public_key["keyid"]
public_key_dict[keyid] = public_key

return public_key_dict
4 changes: 4 additions & 0 deletions tests/check_public_interfaces_gpg.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ def test_gpg_functions(self):
export_pubkey('f00')
self.assertEqual(NO_GPG_MSG, str(ctx.exception))

with self.assertRaises(UnsupportedLibraryError) as ctx:
export_pubkeys(['f00'])
self.assertEqual(NO_GPG_MSG, str(ctx.exception))

with self.assertRaises(UnsupportedLibraryError) as ctx:
get_version()
self.assertEqual(NO_GPG_MSG, str(ctx.exception))
Expand Down
18 changes: 16 additions & 2 deletions tests/test_gpg.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

from securesystemslib import process
from securesystemslib.gpg.functions import (create_signature, export_pubkey,
verify_signature)
verify_signature, export_pubkeys)
from securesystemslib.gpg.util import (get_version, is_version_fully_supported,
get_hashing_class, parse_packet_header, parse_subpacket_header)
from securesystemslib.gpg.rsa import create_pubkey as rsa_create_pubkey
Expand All @@ -55,7 +55,8 @@
from securesystemslib.gpg.exceptions import (PacketParsingError,
PacketVersionNotSupportedError, SignatureAlgorithmNotSupportedError,
KeyNotFoundError, CommandError, KeyExpirationError)
from securesystemslib.formats import GPG_PUBKEY_SCHEMA
from securesystemslib.formats import (GPG_PUBKEY_SCHEMA,
ANY_PUBKEY_DICT_SCHEMA)


@unittest.skipIf(not HAVE_GPG, "gpg not found")
Expand Down Expand Up @@ -481,6 +482,8 @@ class TestGPGRSA(unittest.TestCase):
unsupported_subkey_keyid = "611A9B648E16F54E8A7FAD5DA51E8CDF3B06524F"
expired_key_keyid = "E8AC80C924116DABB51D4B987CB07D6D2C199C7C"

keyid_768C43 = "7B3ABB26B97B655AB9296BD15B0BD02E1C768C43"

@classmethod
def setUpClass(self):
# Create directory to run the tests without having everything blow up
Expand Down Expand Up @@ -547,6 +550,17 @@ def test_export_pubkey(self):
self.assertDictEqual(key_data, key_data2)


def test_export_pubkeys(self):
"""Test export multiple pubkeys at once. """
key_dict = export_pubkeys([self.default_keyid, self.keyid_768C43],
homedir=self.gnupg_home)

ANY_PUBKEY_DICT_SCHEMA.check_match(key_dict)
self.assertListEqual(
sorted([self.default_keyid.lower(), self.keyid_768C43.lower()]),
sorted(key_dict.keys()))


def test_gpg_sign_and_verify_object_with_default_key(self):
"""Create a signature using the default key on the keyring """

Expand Down

0 comments on commit 42171a2

Please sign in to comment.