namespace fedem::sign {
    struct ManifestData;
    struct ManifestResult;
    class  Manifest;
}

Defined in <sign/Manifest.hh>. Link plugin-sign (needs OpenSSL).

A signed DSO carries two extra ELF sections:

SectionContent
.dso_manifestUTF-8 JSON — the fields below
.dso_sig64 raw bytes — the Ed25519 signature over the manifest JSON bytes

Both are noload,readonly and added by dso-sign via objcopy.

ManifestData

struct ManifestData {
    std::string name;          // addon identifier
    std::string version;       // "1.2.0"
    std::string author;        // "Name <email>"
    std::string sha256;        // hex — SHA-256 of the DSO BEFORE the sections were added
    std::string publicKeyId;   // hex — SHA-256 of the signer's DER public key
    int         abiMajor = 0;  // host-defined
    int         abiMinor = 0;  // host-defined
    std::string timestamp;     // ISO-8601, e.g. "2026-09-08T12:00:00Z"
};

sha256 is computed over the file before signing. Verifier strips the two sections to a temp file, hashes that, and compares — so re-signing does not change the hash.

ManifestResult

struct ManifestResult {
    bool hasManifest = false;
    bool hasSig      = false;
    std::string             manifestJson;   // raw JSON
    std::array<uint8_t,64>  sig{};          // raw signature
    ManifestData            data;           // parsed
    std::string             error;          // non-empty on failure
};

Manifest — static functions

static ManifestResult read( std::string const& soPath );

static std::string toJson( ManifestData const& d );

static bool fromJson( std::string const& json,
                      ManifestData&      out,
                      std::string&       error );
  • read — memory-maps soPath, walks the ELF section table by hand (no libelf), and returns the JSON, the raw signature, and the parsed fields. hasManifest / hasSig say what was found; error is set on I/O or parse failure.
  • toJson — serialises ManifestData to canonical JSON with a fixed key order. dso-sign signs the output of this, so verification must hash the same bytes.
  • fromJson — parses JSON into ManifestData; returns false and sets error on malformed input.

Reading a manifest without verifying

auto m = fedem::sign::Manifest::read( "libCircle.so" );
if( m.hasManifest ) {
    std::cout << m.data.name << ' ' << m.data.version
              << " by " << m.data.author << '\n';
    std::cout << "abi " << m.data.abiMajor << '.' << m.data.abiMinor << '\n';
}

This tells you what the DSO claims. It does not check the signature — use Verifier::verify for that.

Notes

  • The section reader is ELF-only. That is the platform limit on the signing half of the toolkit (the loader itself is portable dlopen).
  • Canonical JSON (fixed insertion order, from toJson) is what makes the signature reproducible — do not hand-edit .dso_manifest.