MobDev.Plugin.Verify (mob_dev v0.5.16)

Copy Markdown View Source

Host-side signature verification for activated mob plugins.

Given a plugin directory + its loaded manifest, this module:

  1. Loads priv/mob_plugin.sig (the signed envelope).
  2. Loads priv/mob_plugin.pub (the plugin author's public key).
  3. Recomputes the file-hash list via Sign.compute_file_hashes/2.
  4. Reconstructs the canonical payload and runs Crypto.verify/3.

Failure modes are distinguished:

  • :missing_signature — no priv/mob_plugin.sig.
  • :missing_pubkey — no priv/mob_plugin.pub.
  • :invalid_signature — sig file present but the signature doesn't verify against the canonical payload reconstructed from disk. This is the failure mode for both manifest tampering and source-file tampering: the recomputed file_hashes no longer match what was signed, so the payload differs and the signature check fails.

Trust (mapping a verified public key to "the host operator approved it") lives in TrustStore and is layered on top of this module.

Summary

Types

Errors load_pubkey/1 can return.

Errors load_signature/1 can return.

Errors verify_plugin/2 can return.

Functions

Loads the raw 32-byte public key from priv/mob_plugin.pub.

Loads the raw 64-byte signature from priv/mob_plugin.sig.

Verifies that the plugin in plugin_dir has a valid signature for the given manifest + the current file contents on disk.

Types

pubkey_error()

@type pubkey_error() :: :missing | :malformed

Errors load_pubkey/1 can return.

sig_error()

@type sig_error() :: :missing | :corrupt

Errors load_signature/1 can return.

verify_error()

@type verify_error() :: :missing_signature | :missing_pubkey | :invalid_signature

Errors verify_plugin/2 can return.

Functions

load_pubkey(plugin_dir)

@spec load_pubkey(Path.t()) ::
  {:ok, MobDev.Plugin.Crypto.pub_key()} | {:error, pubkey_error()}

Loads the raw 32-byte public key from priv/mob_plugin.pub.

Format: a single line of base64 (with = padding) of the raw 32-byte Ed25519 public key, optionally followed by a trailing newline. Plain text so plugin authors can cat it or paste it into a release note.

load_signature(plugin_dir)

@spec load_signature(Path.t()) ::
  {:ok, MobDev.Plugin.Crypto.signature()} | {:error, sig_error()}

Loads the raw 64-byte signature from priv/mob_plugin.sig.

The file is the Crypto.canonical_encode/1 of an envelope map (%{signature: <64-byte sig>, envelope_version: 1}); this function decodes the envelope and returns the inner signature binary.

verify_plugin(plugin_dir, manifest)

@spec verify_plugin(Path.t(), map() | nil) :: :ok | {:error, verify_error()}

Verifies that the plugin in plugin_dir has a valid signature for the given manifest + the current file contents on disk.

Returns :ok on success or one of the distinguished error reasons (see verify_error/0). The caller is responsible for any trust decision; this function only proves that the bytes on disk match what the plugin author signed.