OpenSSL gost engine code example

3.6k views Asked by At

Can anybody help me with example of usage of OpenSSL gost engine. I have to sign data using GOST R 34.10-2001 signature algorithm but can't find any working examples or documention. BTW if I'm not going to use that OpenSSL command line utility is there any sense in modifying that openssl.cnf file? If not how do I load engine in code? And what compile flags are needed to build OpenSSL with static gost engine? Thanks in advance.

----Solution----

Finally the following verifies successfully for me:

ENGINE * LoadEngine()
{
    ENGINE *e = NULL;
    ENGINE_load_gost();
    e = ENGINE_by_id("gost");
    if(!e)
    {
        printf("Filed to get structural reference to engine\n");
    }
    if(!ENGINE_init(e))
    {
        ENGINE_free(e);
        printf("Failed to get functional reference to engine\n");
    }
    ENGINE_set_default(e, ENGINE_METHOD_ALL);
    OpenSSL_add_all_algorithms();
    return e;
}

EVP_PKEY * GenerateKeys(ENGINE *e)
{
    EVP_PKEY *pkey = EVP_PKEY_new();
    EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(NID_id_GostR3410_2001, e);

    EVP_PKEY_paramgen_init(ctx);

    EVP_PKEY_CTX_ctrl(ctx,
        NID_id_GostR3410_2001,
        EVP_PKEY_OP_PARAMGEN,
        EVP_PKEY_CTRL_GOST_PARAMSET,
        NID_id_GostR3410_2001_CryptoPro_A_ParamSet,
        NULL);

    EVP_PKEY_keygen_init(ctx);

    EVP_PKEY_keygen(ctx, &pkey);

    EVP_PKEY_CTX_free(ctx);

    return pkey;
}

int main()
{
    ENGINE *e = NULL;
    EVP_PKEY_CTX *ctx = NULL;
    EVP_PKEY *pkey = NULL;
    unsigned char msg[] = "this is a test message";
    Binary hash(32);
    SHA256_Calc(msg, sizeof(msg), &hash[0]);
    size_t siglen = 0;
    int status = 0;
    e = LoadEngine();
    pkey = GenerateKeys(e);
    ctx = EVP_PKEY_CTX_new(pkey, e);
    if(ctx == NULL)
    {
        printf("Failed to create context\n");
        return -1;
    }

    EVP_PKEY_sign_init(ctx);

    status = EVP_PKEY_sign_init(ctx);
    if(status != 1)
    {
        printf("Failed to init signing context\n");
        return -1;
    }
    status = EVP_PKEY_sign(ctx, NULL, &siglen, &hash[0], hash.size());
    if(status != 1)
    {
        printf("Failed to get signature length\n");
        return -1;
    }   
    Binary signature(siglen);
    status = EVP_PKEY_sign(ctx, &signature[0], &siglen, &hash[0], hash.size());
    if(status != 1)
    {
        printf("Failed to sign a message\n");
        return -1;
    }
    EVP_PKEY_verify_init(ctx);
    bool result = EVP_PKEY_verify(ctx, &signature[0], siglen, &hash[0], hash.size());
    printf("%s\n", result ? "SUCCESS" : "FAILURE");
    ENGINE_cleanup();
}
0

There are 0 answers