Signs a shared object: writes a manifest describing it, signs the manifest, and embeds the manifest and signature as ELF sections in the file itself.

Synopsis

dso-sign <addon.so> --key <developer.key>
         [--name <n>] [--version <v>] [--author "Name <email>"]
         [--abi-major N] [--abi-minor N] [--quiet]

<addon.so> (the first non-option argument) and --key are required.

Options

OptionMeaningDefault
<addon.so>The DSO to sign. Modified in place.
--key <file>PEM Ed25519 private key, from dso-keygen.
--name <n>Manifest name.the file stem (libCircle.solibCircle)
--version <v>Manifest version.1.0.0
--author "Name <email>"Manifest author.parsed from the key file's # Name / # Email header
--abi-major NManifest abiMajor — host-defined ABI major.1
--abi-minor NManifest abiMinor.0
-q, --quietSuppress the progress lines.off
-h, --helpUsage.

What it does

  1. Strip any existing .dso_manifest / .dso_sig (so re-signing is idempotent).
  2. Hash the file — SHA-256 of the stripped bytes → manifest sha256.
  3. Read the private key; derive the signer fingerprint (publicKeyId).
  4. Build the manifest (Manifest::toJson, fixed key order) with the fields above plus an ISO-8601 UTC timestamp.
  5. Sign the manifest bytes with Ed25519 → 64 raw bytes.
  6. Embed via objcopy: .dso_manifest = the JSON, .dso_sig = the signature, both noload,readonly.

objcopy (GNU binutils) must be on PATH.

Examples

dso-sign libCircle.so --key keys/private/alice.key
dso-sign libCircle.so --key keys/private/alice.key \
         --name circle-plugin --version 2.3.1 --abi-major 2

# inspect the result
readelf -p .dso_manifest libCircle.so

Run it as a post-build step:

add_custom_command( TARGET Circle POST_BUILD
    COMMAND dso-sign $<TARGET_FILE:Circle> --key ${SIGNING_KEY}
            --name circle-plugin --version ${PROJECT_VERSION} )

Exit codes

0 success · 1 missing arguments, file / key not found, OpenSSL failure, or objcopy failure (temp files are cleaned up).

Notes

  • In place. Keep an unsigned copy if you need one; there is no --output.
  • Re-sign after every rebuild — a new .so has a new hash.
  • The hash is over the stripped file, so signing twice with the same key and fields is a no-op in content (only the timestamp changes).
  • --abi-major / --abi-minor are yours to define; a host reads them from VerifyResult::data and can refuse a mismatch.