Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/actions/prepare/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ runs:
uses: actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25 # v5.1.0
with:
path: /mnt/kryptik/sources
key: sources-${{ hashFiles('sources.lock') }}
key: sources-v2-${{ hashFiles('sources.lock') }}
# A changed lock restores the previous set and fetches only what is
# new; every file is still hashed against the lock.
restore-keys: ${{ inputs.sources == 'fetch' && 'sources-' || '' }}
Expand All @@ -62,4 +62,4 @@ runs:
uses: actions/cache/save@caa296126883cff596d87d8935842f9db880ef25 # v5.1.0
with:
path: /mnt/kryptik/sources
key: sources-${{ hashFiles('sources.lock') }}
key: sources-v2-${{ hashFiles('sources.lock') }}
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ jobs:
uses: actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25 # v5.1.0
with:
path: /mnt/kryptik/sources
key: sources-${{ hashFiles('sources.lock') }}
key: sources-v2-${{ hashFiles('sources.lock') }}
restore-keys: |
sources-

Expand Down
6 changes: 3 additions & 3 deletions docs/supply-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,9 @@ checks them against kernel.org's published developer keys.

## Open problems

- The GNU keyring is fetched over the network, so a signature checked against
it means "signed by whoever the keyring says". Checking those keys out of
band is manual.
- The GNU keyring is fetched over the network and kept with the sources, so a
signature checked against it means "signed by whoever the keyring said when
it was fetched". Checking those keys out of band is manual.
- The kernel.org signing keys are pinned by fingerprint in
`tools/verify-signatures.sh`, and those fingerprints still need confirming
against kernel.org independently.
Expand Down
11 changes: 11 additions & 0 deletions tools/fetch-sources.sh
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,17 @@ delete it yet - work out why first. See docs/supply-chain.md."
fi
done < <(manifest)

# The GNU keyring, kept with the sources so a cache of them carries it: the
# signature gate checks GNU signatures against it, and ftp.gnu.org does not
# answer every runner every time.
keyring="${KRYPTIK_SOURCES}/.keys/gnu-keyring.gpg"
if [[ ! -s "$keyring" ]]; then
mkdir -p "${KRYPTIK_SOURCES}/.keys"
log "fetching the GNU keyring"
fetch_attempt "https://ftp.gnu.org/gnu/gnu-keyring.gpg" "$keyring" fresh \
|| { rm -f "${keyring}.part"; warn "could not fetch the GNU keyring; tools/verify-signatures.sh fetches it again"; }
fi

if [[ "$MODE" == "lock" ]]; then
sort -k2 "${KRYPTIK_LOCK}.new" > "$KRYPTIK_LOCK"
rm -f "${KRYPTIK_LOCK}.new"
Expand Down
18 changes: 11 additions & 7 deletions tools/verify-signatures.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ have gpg || die "gpg not found. Install gnupg."

KEYDIR="${KRYPTIK_ROOT}/build/work/keys"
SIGDIR="${KRYPTIK_SOURCES}/.signatures"
GNU_KEYRING="${KEYDIR}/gnu-keyring.gpg"
# With the sources, so a cache of them carries it (tools/fetch-sources.sh).
GNU_KEYRING="${KRYPTIK_SOURCES}/.keys/gnu-keyring.gpg"

# A private GNUPGHOME, not --keyring: GnuPG 2.4 with keyboxd silently ignores
# --keyring and verifies against the user's own store.
Expand All @@ -30,7 +31,7 @@ REPORT=""
NOTES="$(dirname "${BASH_SOURCE[0]}")/source-notes.tsv"
for a in "$@"; do
case "$a" in
--refresh) rm -rf "$GNUPGHOME" "$GNU_KEYRING" "${GNU_KEYRING}.imported" ;;
--refresh) rm -rf "$GNUPGHOME" "$GNU_KEYRING" ;;
--fetch-unknown-keys) FETCH_UNKNOWN=1 ;;
--strict) STRICT=1 ;;
--report=*) REPORT="${a#--report=}" ;;
Expand Down Expand Up @@ -67,10 +68,13 @@ report() {
# run, not only with --fetch-unknown-keys (see UNAUDITED_FPRS).
KEYS_MANIFEST="${KRYPTIK_ROOT}/keys.manifest"

mkdir -p "$KEYDIR" "$SIGDIR" "$GNUPGHOME"
mkdir -p "$KEYDIR" "$SIGDIR" "$GNUPGHOME" "$(dirname "$GNU_KEYRING")"
chmod 700 "$GNUPGHOME"

IMPORTED_MARK="${GNUPGHOME}/.kryptik-imported"
# This GNUPGHOME has the GNU keyring in it: kept beside the keys, not beside
# the keyring file, which outlives any one checkout's keys.
GNU_IMPORTED="${GNUPGHOME}/.gnu-keyring-imported"

# A host that throttles (freedesktop.org answers 418 to a busy runner, others
# 429 or 503) is asked again after a pause; a 404 is an answer.
Expand Down Expand Up @@ -157,15 +161,15 @@ import_keys() {
if [[ ! -s "$GNU_KEYRING" ]]; then
quiet_fetch "${CANONICAL_GNU}/gnu-keyring.gpg" "$GNU_KEYRING" || rm -f "$GNU_KEYRING"
fi
if [[ -s "$GNU_KEYRING" && ! -f "${GNU_KEYRING}.imported" ]]; then
if [[ -s "$GNU_KEYRING" && ! -f "$GNU_IMPORTED" ]]; then
log "importing GNU keyring (a few thousand keys, this takes a moment)"
gpg --batch --quiet --import "$GNU_KEYRING" 2>/dev/null || true
count="$(gpg --batch --list-keys 2>/dev/null | grep -c '^pub' || true)"
[[ "$count" =~ ^[0-9]+$ && "$count" -ge 100 ]] && : > "${GNU_KEYRING}.imported"
[[ "$count" =~ ^[0-9]+$ && "$count" -ge 100 ]] && : > "$GNU_IMPORTED"
fi
# Without it nothing a GNU maintainer signed can be checked: a run that
# could not fetch it is not a pass.
if [[ ! -f "${GNU_KEYRING}.imported" ]]; then
if [[ ! -f "$GNU_IMPORTED" ]]; then
rm -f "$IMPORTED_MARK"
if [[ "$STRICT" -eq 1 ]]; then
err "the GNU keyring could not be fetched from ${CANONICAL_GNU}"
Expand All @@ -188,7 +192,7 @@ Run again: what was fetched is kept."

count="$(gpg --batch --list-keys 2>/dev/null | grep -c '^pub' || true)"
[[ "$count" =~ ^[0-9]+$ ]] || count=0
if [[ -f "${GNU_KEYRING}.imported" && "$missing" -eq 0 ]]; then
if [[ -f "$GNU_IMPORTED" && "$missing" -eq 0 ]]; then
printf '%s' "$count" > "$IMPORTED_MARK"
else
rm -f "$IMPORTED_MARK"
Expand Down
Loading