namespace fedem::sign {
    struct VerifyResult;
    class  Verifier;
}

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

VerifyResult

struct VerifyResult {
    TrustLevel   trust       = TrustLevel::UNSIGNED;
    ManifestData data;            // populated when hasManifest
    bool         hasManifest = false;
    std::string  detail;         // human-readable reason
};

Verifier — static functions

static VerifyResult verify( std::string const& soPath,
                            std::string const& trustedKeysDir );

static bool isCached( std::string const& soPath );

static bool shouldLoad( std::string const& policy,
                        TrustLevel         level ) noexcept;

verify

Runs, in order:

  1. Read .dso_manifest + .dso_sig (Manifest::read). None present → UNSIGNED.
  2. Strip the sections to a temp file, compute its SHA-256.
  3. Compare with manifest.sha256. Mismatch → REJECTED.
  4. Scan trustedKeysDir for a *.pub whose fingerprint equals manifest.publicKeyId.
  5. Ed25519-verify .dso_sig over the manifest JSON bytes.
    • invalid signature → REJECTED
    • valid, key found in step 4 → TRUSTED
    • valid, key not found → UNKNOWN

The result is cached by soPath — subsequent calls return the cached value. dlopen pins the inode, so a running process's trust cannot change; one verification per path is correct.

isCached

true if soPath already has a cached result. Use it to suppress duplicate log lines across repeated loads.

shouldLoad

Maps a string policy to a boolean:

policyReturns true for
"off"every level (no verification)
"warn"every level except REJECTED
"strict"only TRUSTED

An unrecognised policy behaves as "strict".

Example

#include <sign/Verifier.hh>
using namespace fedem::sign;

VerifyResult vr = Verifier::verify( "/opt/app/plugins/libCircle.so",
                                    "/etc/app/trusted-keys.d" );

if( !Verifier::isCached( "/opt/app/plugins/libCircle.so" ) )   // first time
    log().info( "{}: {}", trustLevelName(vr.trust), vr.detail );

if( !Verifier::shouldLoad( configPolicy, vr.trust ) )
    throw std::runtime_error( "plugin refused by policy: " + vr.detail );

if( vr.hasManifest && vr.data.abiMajor != HOST_PLUGIN_ABI )
    throw std::runtime_error( "plugin ABI mismatch" );

Notes

  • The trusted-keys directory is read fresh on the first verify for a path; add a key and re-verify a different path to pick it up, or restart.
  • verify does not load the DSO. DSOLoader::loadSigned / loadVerified do both in one call.
  • Files in trustedKeysDir that are not parseable PEM Ed25519 public keys are silently ignored.