Handbook

Signatures and trust

zenpac checks what it downloads before it uses it. This page explains what is checked and which keys are trusted for what.

What’s checked

  • Every package’s SHA-256 against the value in its repo DB, signed repo or not (from Phase 2’s package downloads on).
  • The repo DB’s signature, for every repo with signatures = "required". zp update downloads <db>.sig next to the DB. The new DB is only used if the signature verifies. Otherwise the repo is reported as failed and its previous index stays in use.

The official repos (zen/core, zen/test) aren’t signed yet (spec §9.1), so they default to signatures = "none". User repos default to "required", and an unsigned user repo must say signatures = "none" explicitly.

Which keys are trusted

  • Per namespace: a key is pinned for one namespace, and only verifies files of that namespace. The key of masterfix can never sign a file of zen or of another user’s namespace.
  • By fingerprint: a repo’s fingerprint in repos.d pins the key, and the key’s certificate is stored in /var/lib/zenpac/keys/<namespace>.asc (zp keys trust does both). A certificate in that file whose fingerprint isn’t pinned isn’t trusted.
  • Official keys will be built into zenpac once the official repos are signed, and are never taken from the host.

Managing keys

zp repo add asks about a new repo’s key when it adds the repo (see adding repos). For a repo that’s configured already, trusting its namespace’s key takes two steps. It never happens on the host’s word alone:

$ zp keys trust masterfix
✔  valid     0123 4567 89AB CDEF 0123 4567 89AB CDEF 0123 4567
   Masterfix <masterfix@zenlinux.org>

hint: check the fingerprint with the key's owner, then: zp keys trust masterfix <fingerprint>

$ zp keys trust masterfix "0123 4567 89AB CDEF 0123 4567 89AB CDEF 0123 4567"
✔ trusted 0123 4567 89AB CDEF 0123 4567 89AB CDEF 0123 4567 for masterfix (masterfix/tools)
  1. Look: without a fingerprint, zp keys trust downloads <namespace>/key.asc from the namespace’s source and shows what it holds.
  2. Check: compare the fingerprint with one you got from the key’s owner another way, e.g. their profile page or a message.
  3. Trust: with the fingerprint, zenpac downloads the keys again and takes only the certificate with exactly that fingerprint, if it can sign. It stores it in /var/lib/zenpac/keys/<namespace>.asc and pins the fingerprint for every repo of the namespace, in repos.d/99-zenpac.toml.

The other commands:

  • zp keys list shows every pinned key with its state: valid, expired, revoked, unusable (it can’t sign), or missing (pinned, but its certificate isn’t stored).
  • zp keys refresh downloads the published keys again and stores newer certificates of the pinned ones, e.g. with an extended expiry or a revocation. It never adds a key. A pinned key that the namespace no longer publishes is reported, and changing to a new key takes zp keys trust again. refresh exits with code 3 if a key is no longer usable or published.
  • zp keys revoke <namespace> removes the managed pins and the stored certificates, so nothing of the namespace verifies until a key is trusted again. A pin you wrote into your own file stays, and is reported.

Which signatures count

A signature verifies only if all of this holds:

  • it’s a binary signature (OpenPGP type 0x00) made with SHA-224, SHA-256, SHA-384, SHA-512 or SHA-3, never MD5, SHA-1 or RIPEMD-160;
  • it was made at most 5 minutes in the future, not before the key that made it, and hasn’t expired;
  • the key that made it belongs to a pinned certificate of the namespace, and the certificate’s newest valid self-signature shows it neither expired nor revoked;
  • a subkey also needs a valid binding signature that allows signing, with the subkey’s own back-signature, so nobody can attach another person’s subkey to their certificate.

When a check fails, zp update names the reason, e.g. masterfix/tools: the key 0123… is expired or masterfix/tools: not signed by a trusted key of masterfix.

From zenpac’s documentation: docs/user/trust.md at v0.9.5.