From 3ac7b480256868abc0fa712e5bf43a0abd96ab11 Mon Sep 17 00:00:00 2001 From: Kunal Mehta Date: Tue, 24 Sep 2024 16:47:43 -0400 Subject: [PATCH] Verify PGP key embedded in .sources files are correct It's kind of hard to manually test the PGP key inside apt's .sources files are the ones we intended, so write a test to do it. This is copied from the one I wrote in securedrop-client, and adds coverage for the apt-test sources file. This isn't a launcher test, but it needs to have external dependencies installed, so this is the best place for it now until we have unit tests for the rest of the provisioning code. --- launcher/tests/test_sources.py | 42 +++++++++++++++++++++++ poetry.lock | 61 ++++++++++++++++++++++++++++++++-- pyproject.toml | 2 ++ 3 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 launcher/tests/test_sources.py diff --git a/launcher/tests/test_sources.py b/launcher/tests/test_sources.py new file mode 100644 index 00000000..65eb0684 --- /dev/null +++ b/launcher/tests/test_sources.py @@ -0,0 +1,42 @@ +""" +Test apt sources files + +Strictly speaking this doesn't have to do with the launcher, but +it needs dependencies installed and to be run under pytest +""" +from pathlib import Path + +import pysequoia +from debian import deb822 + +SECUREDROP_SALT = Path(__file__).parent.parent.parent / "securedrop_salt" + + +def test_prod_sources(): + """Verify the key in the aptsources file is our prod signing key""" + path = SECUREDROP_SALT / "apt_freedom_press.sources.j2" + + sources = deb822.Sources(path.read_text()) + key = pysequoia.Cert.from_bytes(sources["Signed-By"].encode()) + assert key.fingerprint.upper() == "2359E6538C0613E652955E6C188EDD3B7B22E6A3" + assert len(key.user_ids) == 1 + assert ( + str(key.user_ids[0]) + == "SecureDrop Release Signing Key " + ) + assert key.expiration.year == 2027 + + +def test_test_sources(): + """Verify the key in the apt-test sources file is our dev signing key""" + path = SECUREDROP_SALT / "apt-test_freedom_press.sources.j2" + + sources = deb822.Sources(path.read_text()) + key = pysequoia.Cert.from_bytes(sources["Signed-By"].encode()) + assert key.fingerprint.upper() == "83127F68BABB04F3FE9A69AA545E94503FAB65AB" + assert len(key.user_ids) == 1 + assert ( + str(key.user_ids[0]) + == "SecureDrop TESTING key " + ) + assert key.expiration is None diff --git a/poetry.lock b/poetry.lock index b142d0ed..9c04488b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,15 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. + +[[package]] +name = "chardet" +version = "5.2.0" +description = "Universal encoding detector for Python 3" +optional = false +python-versions = ">=3.7" +files = [ + {file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"}, + {file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"}, +] [[package]] name = "colorama" @@ -250,6 +261,38 @@ files = [ {file = "PyQt5_sip-12.11.0.tar.gz", hash = "sha256:b4710fd85b57edef716cc55fae45bfd5bfac6fc7ba91036f1dcc3f331ca0eb39"}, ] +[[package]] +name = "pysequoia" +version = "0.1.24" +description = "Provides OpenPGP facilities using Sequoia-PGP library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pysequoia-0.1.24-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:4301e081aaa67a39c15acc8cc4692267a24f4001363dca40dc30c0d219a1053b"}, + {file = "pysequoia-0.1.24-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cc5d2e0613e79ad2535cb4e929b82500e6ba54a1d7764e4cb52920cdeae7cad3"}, + {file = "pysequoia-0.1.24-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c1be5372bec9dbb7bc625d1a618e8528118f1fae4da0d93958dcaf36d86e824"}, + {file = "pysequoia-0.1.24-cp310-none-win_amd64.whl", hash = "sha256:307169078ccb4f256f8243f6852b2dbb536c5b7f99dddf135d6d18c04f3cccb9"}, + {file = "pysequoia-0.1.24-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:71cb2e3ec5169b3d41b0d8219c29912f699043c60dee4d2dd99e16ba418bd493"}, + {file = "pysequoia-0.1.24-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c70224872b5cd4912081fb994129c9767fe5768d99bdfe3a37e275e241ecfe12"}, + {file = "pysequoia-0.1.24-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7500cc92a5ec309230c43e9da8e25d3932f82d4338d70d607d1d3f0597b450e8"}, + {file = "pysequoia-0.1.24-cp311-none-win_amd64.whl", hash = "sha256:574db1f7474550035963e3cd1398325c587df257cec57589bdefaeeb971a18d4"}, + {file = "pysequoia-0.1.24-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:358473ed5ff8602b9b6daf0653bdf92610ba989b9b4d4f9f40a512798044785c"}, + {file = "pysequoia-0.1.24-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:399cdd8df3761eb2c68d9b3d741cfb6530e48078a8d84ad3366bbd670975fb69"}, + {file = "pysequoia-0.1.24-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0cf987235a38e59490a8e69f9adc618b31dac34cb1bacd4f51ffc0ff80e6206e"}, + {file = "pysequoia-0.1.24-cp312-none-win_amd64.whl", hash = "sha256:2920c06471097b4b81c2c7bfd4ac3dff4c66c7f1276625e53a338bb1f8698e16"}, + {file = "pysequoia-0.1.24-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:111cfb5503824f62b113d316a385c5f8b8ad6ad2a75ac81f5a7ecf4ca8e2f39b"}, + {file = "pysequoia-0.1.24-cp37-none-win_amd64.whl", hash = "sha256:0e698d00bb0fe07f574e10305eab587fa7341ce7b87a8f20190a511aad24fc15"}, + {file = "pysequoia-0.1.24-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a10272331f522ed4900213a53a07e7a84d777ca932c2391388032ab2eb00dbe3"}, + {file = "pysequoia-0.1.24-cp38-none-win_amd64.whl", hash = "sha256:7884c1838d99314d3b09c294918979e87e8031793aea3c31445943e5bab4e9e0"}, + {file = "pysequoia-0.1.24-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:375436a329c5fbc8f14c0291d00316dd9ea6d5fd5b4d79584621fa060558a147"}, + {file = "pysequoia-0.1.24-cp39-none-win_amd64.whl", hash = "sha256:23b25b11bac9112234127ac70b5546907d69c2b7f912d830118e67a43fc5e26c"}, + {file = "pysequoia-0.1.24-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df945f762ce8541fa6dcc6afcf1df80a2daa22f51610f177fe16d81b3d76631e"}, + {file = "pysequoia-0.1.24-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23fe45ab006237794d3bab9beffa506b8a7c4193c707df297369e78dd13d8c96"}, + {file = "pysequoia-0.1.24-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d7cb24b4aacce92bed135f72d61c1027ead34c56bd7bcf460474741fbc2cd3d"}, + {file = "pysequoia-0.1.24-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4e7ab1af7a4a0d92f4ac7634fc68cd17d64c934b412f374eb6fa8484d72bcfa"}, + {file = "pysequoia-0.1.24.tar.gz", hash = "sha256:b0b18f572515875331009cfcf77df1180c5a23dfb42ff0fac158b2e4044b7b8e"}, +] + [[package]] name = "pytest" version = "8.3.3" @@ -288,6 +331,20 @@ pytest = ">=4.6" [package.extras] testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] +[[package]] +name = "python-debian" +version = "0.1.49" +description = "Debian package related modules" +optional = false +python-versions = ">=3.5" +files = [ + {file = "python-debian-0.1.49.tar.gz", hash = "sha256:8cf677a30dbcb4be7a99536c17e11308a827a4d22028dc59a67f6c6dd3f0f58c"}, + {file = "python_debian-0.1.49-py3-none-any.whl", hash = "sha256:880f3bc52e31599f2a9b432bd7691844286825087fccdcf2f6ffd5cd79a26f9f"}, +] + +[package.dependencies] +chardet = "*" + [[package]] name = "ruff" version = "0.6.7" @@ -340,4 +397,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "4e082bf855ababae6bd499e08a44b7add7f42644915070fb0e664d0923c6b679" +content-hash = "4b6023fc45e0cc4e87e751723b1f4b7223f7012c6b2ce72c6094e62b219a2d1d" diff --git a/pyproject.toml b/pyproject.toml index e1354117..683183e9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,6 +20,8 @@ pytest = "^8.3.3" pytest-cov = "^5.0.0" types-setuptools = "^75.1.0" ruff = "^0.6.7" +python-debian = "^0.1.49" +pysequoia = "^0.1.24" [tool.ruff] line-length = 100