Skip to content

Verify a download

Arkazzae edited this page Oct 7, 2026 · 1 revision

Verify a SafeHouse ZIP before you install it by hand, so you know it was signed with the SafeHouse release key and has not changed since. SafeHouse runs this check itself on every update it installs, but not on a ZIP you upload on the Plugins screen. For what a valid signature proves and what it does not, see Signed updates.

The commands on this page were tested against the SafeHouse 0.2.0 release.

Before you start

You need:

  • the three files from the release on the Releases page: shouse-x.y.z.zip, manifest.json and manifest.json.sig
  • OpenSSL 3.0 or later, or PHP 7.2 or later with the sodium extension

On macOS, the system's openssl command is LibreSSL. Install OpenSSL 3 with Homebrew (brew install openssl@3), or use the PHP method.

Get the files

Download all three files into one folder. With the GitHub CLI, for version 0.2.0:

gh release download v0.2.0 -R designhouseme/SafeHouse

Check the signature with OpenSSL

  1. Save the SafeHouse release public key in a file named safehouse-release.pem:

    -----BEGIN PUBLIC KEY-----
    MCowBQYDK2VwAyEASOrVjhZX5PC6q78ohxcoO9zqcll7YarqDyF6hQ6knBg=
    -----END PUBLIC KEY-----
    

    This is the same key as SOrVjhZX5PC6q78ohxcoO9zqcll7YarqDyF6hQ6knBg= in the plugin's Updater.php, written in the PEM format OpenSSL reads. Compare the two before you trust this page.

  2. Turn the signature into binary:

    base64 -d manifest.json.sig > manifest.json.sig.bin
  3. Check the signature:

    openssl pkeyutl -verify -pubin -inkey safehouse-release.pem -rawin -in manifest.json -sigfile manifest.json.sig.bin

    When the signature is valid, the output is:

    Signature Verified Successfully
    

    Anything else, such as Signature Verification Failure, means the manifest was not signed with this key or was changed afterwards.

Check the signature with PHP

Run this in the folder with the files:

php -r 'echo sodium_crypto_sign_verify_detached(base64_decode(trim(file_get_contents("manifest.json.sig"))), file_get_contents("manifest.json"), base64_decode("SOrVjhZX5PC6q78ohxcoO9zqcll7YarqDyF6hQ6knBg=")) ? "signature OK\n" : "signature INVALID\n";'

When the signature is valid, the output is signature OK.

If you have a clone of the repository, php dev/release-tool.php verify SOrVjhZX5PC6q78ohxcoO9zqcll7YarqDyF6hQ6knBg= manifest.json does the same and reads manifest.json.sig next to the manifest.

Check the ZIP against the manifest

  1. Compute the ZIP's SHA-256 checksum:

    sha256sum shouse-0.2.0.zip

    On macOS, use shasum -a 256 shouse-0.2.0.zip.

  2. Compare the result with the sha256 value in manifest.json. For 0.2.0 both are:

    3d2dfbaefd0bbc6835976c63ad145be10d364f59c4ed4c0f7f12eb7153393eb9
    
  3. Check that version in manifest.json is the version you meant to install.

When the signature is valid and the checksums match, the ZIP is the one the SafeHouse release process signed.

If verification fails

Do not install the ZIP. Download the three files again from the Releases page and repeat the checks. If they still fail, report it privately on the repository's Security tab with Report a vulnerability, and say which files and commands you used.

Rebuild the ZIP from source

The release build is reproducible: building the same tag again gives a byte-identical ZIP. This lets you check that the published ZIP contains exactly the code in the repository. You need git and Docker; the build runs PHP in the composer:2 Docker image.

Use the build tools from the release's own tag, because the tools change between releases.

  1. Clone the repository at the release tag:

    git clone --branch v0.2.0 https://github.com/designhouseme/SafeHouse.git safehouse-0.2.0
    cd safehouse-0.2.0
  2. Create a throwaway signing key. The build signs what it builds, so it needs a key, but the key does not change the ZIP:

    SHOUSE_SIGNING_KEY=/tmp/safehouse-test.key ./dev/release.sh keygen
  3. Build the ZIP. For 0.2.0, whose tools predate the build command, use snapshot:

    SHOUSE_SIGNING_KEY=/tmp/safehouse-test.key ./dev/release.sh snapshot 0.2.0 /tmp/safehouse-build

    For later releases, use ./dev/release.sh build x.y.z /tmp/safehouse-build. It writes the ZIP first and then stops with "the signing key (…) is not in PUBLIC_KEYS", because your throwaway key is not the release key. That is expected.

  4. Compare the checksum of /tmp/safehouse-build/shouse-0.2.0.zip with the published one. They are identical.

Related pages

Clone this wiki locally