# Signing the DragonX bootstrap archive

`util/bootstrap-dragonx.sh` verifies a detached signature of `DRAGONX.zip` against a
public key **embedded in the script** (`BOOTSTRAP_PUBKEY`). Because the key ships in the
repo/binary and is not downloaded from the bootstrap server, a compromised bootstrap host
cannot forge a valid signature — unlike the `.md5`/`.sha256` files, which are served from
the same host and only detect corruption.

Until a real key is embedded, `BOOTSTRAP_PUBKEY` is the placeholder and the script skips
signature enforcement (with a warning), so existing users are unaffected. Once a real key
is pasted in, an unsigned or invalid bootstrap is **refused**.

## One-time: create the signing keypair (offline)

Keep the private key OFFLINE (air-gapped if possible). Ed25519 or RSA-4096 both work with
the `openssl dgst -sha256 -verify` check the script uses; RSA-4096 maximizes compatibility:

```sh
# Private key — keep secret, never publish
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out dragonx-bootstrap.key
# Public key — paste into bootstrap-dragonx.sh
openssl pkey -in dragonx-bootstrap.key -pubout -out dragonx-bootstrap.pub
cat dragonx-bootstrap.pub
```

Paste the full PEM (including the `-----BEGIN/END PUBLIC KEY-----` lines) into
`BOOTSTRAP_PUBKEY` in `util/bootstrap-dragonx.sh`, e.g.:

```sh
BOOTSTRAP_PUBKEY="$(cat <<'PEM'
-----BEGIN PUBLIC KEY-----
... base64 ...
-----END PUBLIC KEY-----
PEM
)"
```

## Each release: sign the archive and publish the signature

```sh
openssl dgst -sha256 -sign dragonx-bootstrap.key -out DRAGONX.zip.sig DRAGONX.zip
```

Upload `DRAGONX.zip.sig` next to `DRAGONX.zip` (and its `.md5`/`.sha256`) on every
bootstrap host (`bootstrap.dragonx.is`, `bootstrap2.dragonx.is`). Verify locally first:

```sh
openssl dgst -sha256 -verify dragonx-bootstrap.pub -signature DRAGONX.zip.sig DRAGONX.zip
# -> "Verified OK"
```

## Rotating the key

Embed the new public key in the script, sign future archives with the new private key, and
release a new client version. Old clients keep trusting the old key; coordinate the cutover
with a release so users upgrade before the old key is retired.
