惊雷无声 发表于 2024-7-24 21:39:25

OpenSSL Engine的三种加载方式

本文测试代码基于Openssl版本:1.1.1f
创建一个Engine lib

#include <openssl/evp.h>
#include <openssl/engine.h>
#include <iostream>

static int encryptfn(EVP_PKEY_CTX *ctx,unsigned char *out,size_t *outlen,const unsigned char *in,size_t inlen){
*outlen = 1;
std::cout << "encryptfn call" << std::endl;
return 1;
}

static int test_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
                           const int **pnids, int nid)
{
    static const int rnid = EVP_PKEY_RSA;
    if (pmeth == NULL) {
      *pnids = &rnid;
      return 1;
    }

    if (nid == EVP_PKEY_RSA) {
      EVP_PKEY_METHOD* method{EVP_PKEY_meth_new(0,0)};
      EVP_PKEY_meth_set_encrypt(method, nullptr, encryptfn);//设置自定义方法
      *pmeth = method;
      return 1;
    }

    *pmeth = NULL;
    return 0;
}

static std::int32_t bind(ENGINE* const e, const char* const id) {
std::int32_t ret{0};
ENGINE_set_id(e,"test_ID");
ENGINE_set_name(e,"test_name");

ENGINE_set_pkey_meths(e,test_pkey_meths);

return 1;
}

extern "C" std::int32_t bind_engine(ENGINE* const e, const char* const id,
                                    const dynamic_fns* const fns);
extern "C" std::int32_t bind_engine(ENGINE* const e, const char* const id,
                                    const dynamic_fns* const fns) {
if (ENGINE_get_static_state() == fns->static_state) {
    if (0 == bind(e, id)) {
      return 0;
    }
    return 1;
}

static_cast<void>(CRYPTO_set_mem_functions(
      fns->mem_fns.malloc_fn, fns->mem_fns.realloc_fn, fns->mem_fns.free_fn));
if (0 == bind(e, id)) {
    return 0;
}
return 1;
}


extern "C" uint64_t v_check(const uint64_t v) noexcept;
extern "C" uint64_t v_check(const uint64_t v) noexcept {
if (v >= static_cast<uint64_t>(0x00030000U)) {
    return static_cast<uint64_t>(0x00030000U);
}
return 0U;
}编译动态库:g++ -fPIC -shared engine_evp_so.cpp -o libengine_evp.so

Engine 加载方式1:cmd加载

方法1:openssl cmd加载

> engine dynamic -pre SO_PATH:/yourpath/libengine_evp.so -pre LOAD
(dynamic) Dynamic engine loading support
: SO_PATH:/yourpath/libengine_evp.so
: LOAD
Loaded: (test_ID) test_name
方法2:进程中调用cmd函数加载

在代码中使用ENGINE_ctrl_cmd_string()调用cmd能力来加载engine
#include #include #include void dump_hex(const uint8_t *hex, uint32_t size) {uint32_t i = 0;for (i = 0; i < size; ++i) {    if ((i % 8) == 0) {      printf("\n");    }    printf("0x%02x ", hex);}printf("\n");}RSA* rsa_create(){    RSA* rsa = RSA_new();//分配空间    BIGNUM* pBNe = BN_new();//分配空间    BN_set_word(pBNe, RSA_F4);    int ret = RSA_generate_key_ex(rsa, 1024, pBNe, NULL);    if(ret < 0 ){      printf("encrypt failed, ret:%d \n", ret);      return nullptr;    }    BN_free(pBNe);    return rsa;}int main(){ENGINE_load_dynamic();//加载dynamic engineENGINE* engine = ENGINE_by_id("dynamic");if(engine == nullptr){    std::cout
页: [1]
查看完整版本: OpenSSL Engine的三种加载方式