|
| 1 | +#!/usr/bin/env python |
| 2 | +""" |
| 3 | +<Program Name> |
| 4 | + check_public_interfaces_gpg.py |
| 5 | +
|
| 6 | +<Author> |
| 7 | + Lukas Puehringer <[email protected]> |
| 8 | +
|
| 9 | +<Started> |
| 10 | + Feb 26, 2020. |
| 11 | +
|
| 12 | +<Copyright> |
| 13 | + See LICENSE for licensing information. |
| 14 | +
|
| 15 | +<Purpose> |
| 16 | + Check that the public facing 'gpg.functions' module remains importable if |
| 17 | + gnupg is not installed, and that each function presents meaningful |
| 18 | + user-feedback. |
| 19 | + Further check that gpg signature verification works even without gpg. |
| 20 | +
|
| 21 | + NOTE: the filename is purposefully check_ rather than test_ so that test |
| 22 | + discovery doesn't find this test module and the test cases within are only |
| 23 | + run when explicitly invoked. |
| 24 | +
|
| 25 | +""" |
| 26 | +import unittest |
| 27 | +from securesystemslib.gpg.constants import HAVE_GPG, NO_GPG_MSG |
| 28 | +from securesystemslib.gpg.util import get_version |
| 29 | +from securesystemslib.gpg.functions import ( |
| 30 | + create_signature, export_pubkey, verify_signature) |
| 31 | + |
| 32 | +from securesystemslib.exceptions import UnsupportedLibraryError |
| 33 | + |
| 34 | + |
| 35 | +class TestPublicInterfacesGPG(unittest.TestCase): |
| 36 | + @classmethod |
| 37 | + def setUpClass(cls): |
| 38 | + assert not HAVE_GPG, \ |
| 39 | + "please remove GnuPG from your environment to run this test case" |
| 40 | + |
| 41 | + def test_gpg_functions(self): |
| 42 | + """Signing, key export and util functions must raise on missing gpg. """ |
| 43 | + with self.assertRaises(UnsupportedLibraryError) as ctx: |
| 44 | + create_signature('bar') |
| 45 | + self.assertEqual(NO_GPG_MSG, str(ctx.exception)) |
| 46 | + |
| 47 | + with self.assertRaises(UnsupportedLibraryError) as ctx: |
| 48 | + export_pubkey('f00') |
| 49 | + self.assertEqual(NO_GPG_MSG, str(ctx.exception)) |
| 50 | + |
| 51 | + with self.assertRaises(UnsupportedLibraryError) as ctx: |
| 52 | + get_version() |
| 53 | + self.assertEqual(NO_GPG_MSG, str(ctx.exception)) |
| 54 | + |
| 55 | + def test_gpg_verify(self): |
| 56 | + """Signature verification does not require gpg to be installed on the host. |
| 57 | + To prove it, we run basic verification tests for rsa, dsa and eddsa with |
| 58 | + pre-generated/exported signatures and keys. More thorough testing is |
| 59 | + available in test_gpg.py |
| 60 | +
|
| 61 | + """ |
| 62 | + data = b"deadbeef" |
| 63 | + key_signature_pairs = [ |
| 64 | + # RSA |
| 65 | + ({'method': 'pgp+rsa-pkcsv1.5', 'type': 'rsa', 'hashes': ['pgp+SHA2'], 'creation_time': 1519661780, 'keyid': 'c5a0abe6ec19d0d65f85e2c39be9df5131d924e9', 'keyval': {'private': '', 'public': {'e': '010001', 'n': 'c152fc1f1535a6d3c1e8c0dece7f0a1d09324466e10e4ea51d5d7223ab125c1743393eebca73ccb1022d44c379fae30ef63b263d0a793882a7332ef06f28a4b9ae777f5d2d8d289167e86c162df1b9a9e127acb26803688556ecb08492d071f06caf88cea95571354349d8ef131eff03b0d259fae30ebf8dac9ab5acd6f26f4770fe2f30fcd0a3c54f03463a3094aa6524e39027a625108f04e12475da248fb3b536df61b0f6e2954739b8828c61171f66f8e176823e1c887e65fa0aec081013b2a50ed60515f7e3b3291ca443e1222b9b625005dba045a7208188fb88d436d473f6340348953e891354c7a5734bf64e6274e196db3074a7ce3607960baacb1b'}}}, |
| 66 | + {'keyid': 'c5a0abe6ec19d0d65f85e2c39be9df5131d924e9', 'other_headers': '04000108001d162104c5a0abe6ec19d0d65f85e2c39be9df5131d924e905025e56444b', 'signature': 'bc4490901bd6edfe0ec49e0358c0a7ef37fc229824ca75dd4f163205745c78baaa2ca5cda79be259a5ac8323b4c1a1ee18fab0a8cc90eeafeb3eb1221d4bafb55510f34cf99e7ac121874f3c01152d6d8953c661c3e5147a387fffaee672318ed39c49fa02c80fa806956695f2fdfe0429a61639e7fb544f1531100eb02b7a140ffa284746fa1620e8461e4af5f93594f8aed6d34a33d51b265bae90ea8bedccb7497594003eb46516bddb1778a4fadd02cbb227e1931eeb5ef445fb9745f85cfbebfa169c3ae7d15e2ca75b15dd020877c9a968ff853993a06420d3c3ff158800014f21e558103cd4e7e84cf5e320ebf7c525e0eab9ab22ad4af02c7ad48b5e'}), |
| 67 | + # DSA |
| 68 | + ({'method': 'pgp+dsa-fips-180-2', 'type': 'dsa', 'hashes': ['pgp+SHA2'], 'creation_time': 1510870182, 'keyid': 'c242a830daaf1c2bef604a9ef033a3a3e267b3b1', 'keyval': {'private': '', 'public': {'y': '2dd50b2292441444581f9a0b7d8d7f88b573fc451f5e7207c324694232c22e171b508f6842ae9babc56fe4e586a22086188b4827b7aba8c7bff4a4ac9aa80c835420b1afba4ab4f1b1c0ef894437903a9f4c56ebef037804a99925c9a153b8a16c1562f297755aeaa20fa02ab32aa5366e052b6baa9a934356d4f5fc218785018dd12b2c8e6d605d2afb36cb06a9cced9ea1f5f82798d635de264ef0eb59590c4a4b2fdf2369a36f95614804c7aa5966ba9597404ba2d2c6881959112de52de4b6d4f1e2c8a59ddaadb08a59ac8334118f15aa01593e851024905ea6d884c3a545af6fdd03c8d2b54da1d35e710ef75a2b4775bb78c50b28d1e2fb48416dc941', 'p': 'fca3276cd78c20e3c73ae2398674046039f5d90f41e3ede9bc99f94000d145693522671fba481d22e0a9b31e695d198da5e62f4ffb4db5dc64076d0f2d7d03ce953fc7846a6d4e17a10bf1dcd17167f7aff761b59fa2180e7fcd2ca527c03c50c78665b5539bf2b45648b6d23f31f37999e6a7b4e0876ddad7ec783b8eec7e1fb14733e74b6b0b105cbdc5a7de8e094657f2146ce43a3177581cb022a4e2ce6678a3364a56e02090559a6dfd81d91ca3b7c6afd4fcfc66fd88339d217062462f51c5c91d6eccfafb32065be68e6b91ec837c59a51baebeca1c70fd3891c9bbb67f7d920f9153fc4d2ca03f88a27b70df1684709f99ad18707189b015441b2bfb', 'g': '7f7252ae1824baf2be5fc8f431a1978683a38d4a22cc2bcdc01ccd1f5eee47a964aa57639a618cfb1b10707b4d09ff11a448e83ba70123573f2d49a599f5313a74463e5bb3ca3d6172a00f02b01065ce312501e1797f7b57e606947c44bd839fde8d43269f1fb74af6cedf4db7fabf0b2357ed09d56381ac769ef5a8af1b4450e0c88b64ee1cab9fadeb31b7be6207b7e17008a33a7613831f70a123d59279dcbc2238f46eeaa8097795b7805f1b837ef3b8e807164e186fae9fa3ff510213096bf54040eac545a6a5b47c910e6cf7e306e1f46723f14b02cd9e0b0ff2a56c3b2604869431ab3263d61bf5068bee36c880c7bf2c746dcae5d0d7b2fff244ef43', 'q': '84779eeae0238d7a9a030a639bf01a0f9ef517a5d950599c19a4e54fbbf23219'}}}, |
| 69 | + {'keyid': 'c242a830daaf1c2bef604a9ef033a3a3e267b3b1', 'other_headers': '04001108001d162104c242a830daaf1c2bef604a9ef033a3a3e267b3b105025e5644d1', 'signature': '3044022009e95f952f64f559852fb6b321173f3cb142a5dbe0c84d709d55026ab945582802203144ee0f4c2cb70fa00ca6942c847208b96811271445ed85c75ebebdb609b174'}), |
| 70 | + # EDDSA |
| 71 | + ({'method': 'pgp+eddsa-ed25519', 'type': 'eddsa', 'hashes': ['pgp+SHA2'], 'creation_time': 1572269200, 'keyid': '4e630f84838bf6f7447b830b22692f5fea9e2dd2', 'keyval': {'private': '', 'public': {'q': '716e57b8c5d4397a4194f80bd43af2e07691db7ee58d2473ceb56cef1eda7569'}}}, |
| 72 | + {'keyid': '4e630f84838bf6f7447b830b22692f5fea9e2dd2', 'other_headers': '04001608001d1621044e630f84838bf6f7447b830b22692f5fea9e2dd205025e564505', 'signature': '70ba3fe785bccac105b837b6b27cc8d5ddd0159c3f640bbac026b744e0b10839bf4ea53e786074d32f9617389a4fe3356ec1c4a19045c5c02821563786e1d10d'}) |
| 73 | + ] |
| 74 | + |
| 75 | + for key, sig in key_signature_pairs: |
| 76 | + self.assertTrue(verify_signature(sig, key, data)) |
| 77 | + |
| 78 | + |
| 79 | +if __name__ == "__main__": |
| 80 | + unittest.main(verbosity=1, buffer=True) |
0 commit comments