Skip to content

Commit 2497888

Browse files
Make the package signature verification actually work
The Docker image has not been buildable since v1.4.1. Adding packages/CHECKSUMS.sha256.asc on 2026-07-15 switched on a verification branch in the Dockerfile that had never once executed, and it failed immediately: python:3.12.11-slim ships no gpg. Building v1.4.1 today reproduces it exactly. The native path was broken too, for a different reason. bootstrap-linux.sh and bootstrap-macos.sh call gpg --verify without ever importing the public key, so on any machine that does not already have it in its keyring gpg exits 2 with "No public key" and the script aborts the install. That is almost every user. The public key is now in the repo. The copy published on the docs site could not be imported at all: it was missing the blank line the armor format requires between the header and the base64 body, so gpg rejected it as an invalid armor header. That is fixed here. The Dockerfile installs gnupg, imports the key, verifies, then purges gnupg in the same layer so it does not reach the final image. The bootstrap scripts import the bundled key, and when gpg is absent they now warn loudly and fall through to the SHA-256 check instead of aborting: this tool is meant to run on air-gapped machines where installing gnupg may be impossible, and refusing to install there would fail in exactly the case it exists for. Verified: the build prints Good signature from S.A.S.U. KATVIO (Fractum Release Signing), the image is 260 MB with gpg absent from it, an encrypt/decrypt round trip through the image with --network=none returns an identical SHA-256, two shares below the threshold still fail, and the suite is 107 tests, 8/8 files.
1 parent a6887b4 commit 2497888

4 files changed

Lines changed: 116 additions & 9 deletions

File tree

Dockerfile

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,22 @@ COPY setup.py README.md LICENSE TRADEMARK.md SECURITY.md bootstrap-linux.sh boot
66
COPY src/ /app/src/
77
COPY tests/ /app/tests/
88
COPY packages/ /app/packages/
9+
COPY fractum-signing-key.asc /app/fractum-signing-key.asc
910

1011
# Install dependencies — verify offline packages if present (M6)
12+
# La verification GPG etait inoperante depuis la v1.4.1 : le fichier .asc a ete
13+
# ajoute le 2026-07-15, ce qui a active cette branche pour la premiere fois,
14+
# alors que l'image de base ne contient pas gpg et que la cle publique n'etait
15+
# nulle part. L'image n'etait donc plus constructible du tout. On installe
16+
# gnupg, on importe la cle du depot, et on verifie pour de bon.
1117
RUN if [ -f packages/CHECKSUMS.sha256 ] && [ -f packages/CHECKSUMS.sha256.asc ]; then \
12-
gpg --verify packages/CHECKSUMS.sha256.asc packages/CHECKSUMS.sha256 \
18+
apt-get update && apt-get install -y --no-install-recommends gnupg; \
19+
gpg --batch --quiet --import /app/fractum-signing-key.asc \
20+
|| { echo "ERROR: cannot import the Fractum signing key"; exit 1; }; \
21+
gpg --batch --verify packages/CHECKSUMS.sha256.asc packages/CHECKSUMS.sha256 \
1322
|| { echo "ERROR: Invalid GPG signature on packages"; exit 1; }; \
23+
apt-get purge -y gnupg && apt-get autoremove -y \
24+
&& rm -rf /var/lib/apt/lists/* /root/.gnupg; \
1425
fi; \
1526
if [ -f packages/CHECKSUMS.sha256 ]; then \
1627
(cd packages && sha256sum --check CHECKSUMS.sha256 --strict --quiet) \

bootstrap-linux.sh

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,35 @@ PYENV_INSTALLER_SHA256="4b0adf623a6205727163eb98610b6c5e63f23b99183948b874d867cd
1111
# Requires packages/CHECKSUMS.sha256 — GPG signature in packages/CHECKSUMS.sha256.asc if present.
1212
verify_packages() {
1313
local pkg_dir="${1:-packages}"
14+
local key_file="${2:-fractum-signing-key.asc}"
1415
echo "→ Verifying package integrity..."
1516

17+
# La signature ne se verifiait jamais : le script appelait gpg sans jamais
18+
# importer la cle publique, donc gpg sortait en « No public key » et le
19+
# script abandonnait l'installation. La cle est desormais dans le depot.
20+
#
21+
# Si gpg est absent, on continue au lieu d'abandonner, et on le dit. Cet
22+
# outil est fait pour tourner sur une machine coupee du reseau, ou installer
23+
# gnupg peut etre impossible ; refuser l'installation la ferait echouer
24+
# precisement dans le cas d'usage qu'elle vise. Les sommes SHA-256 restent
25+
# verifiees juste apres, dans tous les cas.
1626
if [ -f "${pkg_dir}/CHECKSUMS.sha256.asc" ]; then
17-
echo "→ Verifying GPG signature on packages (key D009F6290DCFDAB6)..."
18-
gpg --verify "${pkg_dir}/CHECKSUMS.sha256.asc" "${pkg_dir}/CHECKSUMS.sha256" \
19-
|| { echo "ERROR: Invalid GPG signature on packages — installation aborted"; exit 1; }
20-
echo " ✓ GPG signature valid"
27+
if command -v gpg >/dev/null 2>&1; then
28+
echo "→ Verifying GPG signature on packages (key D009F6290DCFDAB6)..."
29+
if [ -f "${key_file}" ]; then
30+
gpg --batch --quiet --import "${key_file}" \
31+
|| { echo "ERROR: cannot import ${key_file} — installation aborted"; exit 1; }
32+
else
33+
echo " WARNING: ${key_file} not found — relying on a key already in your keyring"
34+
fi
35+
gpg --batch --verify "${pkg_dir}/CHECKSUMS.sha256.asc" "${pkg_dir}/CHECKSUMS.sha256" \
36+
|| { echo "ERROR: Invalid GPG signature on packages — installation aborted"; exit 1; }
37+
echo " ✓ GPG signature valid"
38+
else
39+
echo " WARNING: gpg not installed — the signature on CHECKSUMS.sha256 was NOT checked."
40+
echo " Only the SHA-256 hashes below are verified. Install gnupg and re-run"
41+
echo " this script to check who signed them."
42+
fi
2143
else
2244
echo " WARNING: ${pkg_dir}/CHECKSUMS.sha256.asc not found — skipping GPG verification"
2345
echo " For production use, obtain the .asc from a trusted Katvio release."

bootstrap-macos.sh

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,35 @@ HOMEBREW_INSTALLER_SHA256="2863708cb516c5d0bcdfff97dc13bffb61db93f7acc6ae559a559
1010
# Verify offline packages before installation (M6)
1111
verify_packages() {
1212
local pkg_dir="${1:-packages}"
13+
local key_file="${2:-fractum-signing-key.asc}"
1314
echo "→ Verifying package integrity..."
1415

16+
# La signature ne se verifiait jamais : le script appelait gpg sans jamais
17+
# importer la cle publique, donc gpg sortait en « No public key » et le
18+
# script abandonnait l'installation. La cle est desormais dans le depot.
19+
#
20+
# Si gpg est absent, on continue au lieu d'abandonner, et on le dit. Cet
21+
# outil est fait pour tourner sur une machine coupee du reseau, ou installer
22+
# gnupg peut etre impossible ; refuser l'installation la ferait echouer
23+
# precisement dans le cas d'usage qu'elle vise. Les sommes SHA-256 restent
24+
# verifiees juste apres, dans tous les cas.
1525
if [ -f "${pkg_dir}/CHECKSUMS.sha256.asc" ]; then
16-
echo "→ Verifying GPG signature on packages (key D009F6290DCFDAB6)..."
17-
gpg --verify "${pkg_dir}/CHECKSUMS.sha256.asc" "${pkg_dir}/CHECKSUMS.sha256" \
18-
|| { echo "ERROR: Invalid GPG signature on packages — installation aborted"; exit 1; }
19-
echo " ✓ GPG signature valid"
26+
if command -v gpg >/dev/null 2>&1; then
27+
echo "→ Verifying GPG signature on packages (key D009F6290DCFDAB6)..."
28+
if [ -f "${key_file}" ]; then
29+
gpg --batch --quiet --import "${key_file}" \
30+
|| { echo "ERROR: cannot import ${key_file} — installation aborted"; exit 1; }
31+
else
32+
echo " WARNING: ${key_file} not found — relying on a key already in your keyring"
33+
fi
34+
gpg --batch --verify "${pkg_dir}/CHECKSUMS.sha256.asc" "${pkg_dir}/CHECKSUMS.sha256" \
35+
|| { echo "ERROR: Invalid GPG signature on packages — installation aborted"; exit 1; }
36+
echo " ✓ GPG signature valid"
37+
else
38+
echo " WARNING: gpg not installed — the signature on CHECKSUMS.sha256 was NOT checked."
39+
echo " Only the SHA-256 hashes below are verified. Install gnupg and re-run"
40+
echo " this script to check who signed them."
41+
fi
2042
else
2143
echo " WARNING: ${pkg_dir}/CHECKSUMS.sha256.asc not found — skipping GPG verification"
2244
echo " For production use, obtain the .asc from a trusted Katvio release."

fractum-signing-key.asc

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
-----BEGIN PGP PUBLIC KEY BLOCK-----
2+
3+
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
50+
UVsMvssUriCsGsRic1x7Cr8oAslNY6jJqSapoXQ=
51+
=CkRq
52+
-----END PGP PUBLIC KEY BLOCK-----

0 commit comments

Comments
 (0)