/**********************************************************************
 *                          gost_eng.c                                *
 *             Copyright (c) 2005-2006 Cryptocom LTD                  *
 *         This file is distributed under the same license as OpenSSL *
 *                                                                    *
 *              Main file of GOST engine                              *
 *       for OpenSSL                                                  *
 *          Requires OpenSSL 0.9.9 for compilation                    *
 **********************************************************************/
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/engine.h>
#include <openssl/obj_mac.h>
#include "e_gost_err.h"
#include "gost_lcl.h"
static const char *engine_gost_id = "gost";
static const char *engine_gost_name =
    "Reference implementation of GOST engine";

/* Symmetric cipher and digest function registrar */

static int gost_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
                        const int **nids, int nid);

static int gost_digests(ENGINE *e, const EVP_MD **digest,
                        const int **nids, int ind);

static int gost_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
                           const int **nids, int nid);

static int gost_pkey_asn1_meths(ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth,
                                const int **nids, int nid);

static int gost_cipher_nids[] = { NID_id_Gost28147_89, NID_gost89_cnt, 0 };

static int gost_digest_nids[] =
    { NID_id_GostR3411_94, NID_id_Gost28147_89_MAC, 0 };

static int gost_pkey_meth_nids[] = { NID_id_GostR3410_94,
    NID_id_GostR3410_2001, NID_id_Gost28147_89_MAC, 0
};

static EVP_PKEY_METHOD *pmeth_GostR3410_94 = NULL,
    *pmeth_GostR3410_2001 = NULL, *pmeth_Gost28147_MAC = NULL;

static EVP_PKEY_ASN1_METHOD *ameth_GostR3410_94 = NULL,
    *ameth_GostR3410_2001 = NULL, *ameth_Gost28147_MAC = NULL;

static int gost_engine_init(ENGINE *e)
{
    return 1;
}

static int gost_engine_finish(ENGINE *e)
{
    return 1;
}

static int gost_engine_destroy(ENGINE *e)
{
    gost_param_free();

    pmeth_GostR3410_94 = NULL;
    pmeth_GostR3410_2001 = NULL;
    pmeth_Gost28147_MAC = NULL;
    ameth_GostR3410_94 = NULL;
    ameth_GostR3410_2001 = NULL;
    ameth_Gost28147_MAC = NULL;
    return 1;
}

static int bind_gost(ENGINE *e, const char *id)
{
    int ret = 0;
    if (id && strcmp(id, engine_gost_id))
        return 0;
    if (ameth_GostR3410_94) {
        printf("GOST engine already loaded\n");
        goto end;
    }

    if (!ENGINE_set_id(e, engine_gost_id)) {
        printf("ENGINE_set_id failed\n");
        goto end;
    }
    if (!ENGINE_set_name(e, engine_gost_name)) {
        printf("ENGINE_set_name failed\n");
        goto end;
    }
    if (!ENGINE_set_digests(e, gost_digests)) {
        printf("ENGINE_set_digests failed\n");
        goto end;
    }
    if (!ENGINE_set_ciphers(e, gost_ciphers)) {
        printf("ENGINE_set_ciphers failed\n");
        goto end;
    }
    if (!ENGINE_set_pkey_meths(e, gost_pkey_meths)) {
        printf("ENGINE_set_pkey_meths failed\n");
        goto end;
    }
    if (!ENGINE_set_pkey_asn1_meths(e, gost_pkey_asn1_meths)) {
        printf("ENGINE_set_pkey_asn1_meths failed\n");
        goto end;
    }
    /* Control function and commands */
    if (!ENGINE_set_cmd_defns(e, gost_cmds)) {
        fprintf(stderr, "ENGINE_set_cmd_defns failed\n");
        goto end;
    }
    if (!ENGINE_set_ctrl_function(e, gost_control_func)) {
        fprintf(stderr, "ENGINE_set_ctrl_func failed\n");
        goto end;
    }
    if (!ENGINE_set_destroy_function(e, gost_engine_destroy)
        || !ENGINE_set_init_function(e, gost_engine_init)
        || !ENGINE_set_finish_function(e, gost_engine_finish)) {
        goto end;
    }

    if (!register_ameth_gost
        (NID_id_GostR3410_94, &ameth_GostR3410_94, "GOST94",
         "GOST R 34.10-94"))
        goto end;
    if (!register_ameth_gost
        (NID_id_GostR3410_2001, &ameth_GostR3410_2001, "GOST2001",
         "GOST R 34.10-2001"))
        goto end;
    if (!register_ameth_gost(NID_id_Gost28147_89_MAC, &ameth_Gost28147_MAC,
                             "GOST-MAC", "GOST 28147-89 MAC"))
        goto end;

    if (!register_pmeth_gost(NID_id_GostR3410_94, &pmeth_GostR3410_94, 0))
        goto end;
    if (!register_pmeth_gost(NID_id_GostR3410_2001, &pmeth_GostR3410_2001, 0))
        goto end;
    if (!register_pmeth_gost
        (NID_id_Gost28147_89_MAC, &pmeth_Gost28147_MAC, 0))
        goto end;
    if (!ENGINE_register_ciphers(e)
        || !ENGINE_register_digests(e)
        || !ENGINE_register_pkey_meths(e)
        /* These two actually should go in LIST_ADD command */
        || !EVP_add_cipher(&cipher_gost)
        || !EVP_add_cipher(&cipher_gost_cpacnt)
        || !EVP_add_digest(&digest_gost)
        || !EVP_add_digest(&imit_gost_cpa)
        ) {
        goto end;
    }

    ERR_load_GOST_strings();
    ret = 1;
 end:
    return ret;
}

#ifndef OPENSSL_NO_DYNAMIC_ENGINE
IMPLEMENT_DYNAMIC_BIND_FN(bind_gost)
    IMPLEMENT_DYNAMIC_CHECK_FN()
#endif                          /* ndef OPENSSL_NO_DYNAMIC_ENGINE */
static int gost_digests(ENGINE *e, const EVP_MD **digest,
                        const int **nids, int nid)
{
    int ok = 1;
    if (!digest) {
        *nids = gost_digest_nids;
        return 2;
    }
    /*
     * printf("Digest no %d requested\n",nid);
     */
    if (nid == NID_id_GostR3411_94) {
        *digest = &digest_gost;
    } else if (nid == NID_id_Gost28147_89_MAC) {
        *digest = &imit_gost_cpa;
    } else {
        ok = 0;
        *digest = NULL;
    }
    return ok;
}

static int gost_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
                        const int **nids, int nid)
{
    int ok = 1;
    if (!cipher) {
        *nids = gost_cipher_nids;
        return 2;               /* two ciphers are supported */
    }

    if (nid == NID_id_Gost28147_89) {
        *cipher = &cipher_gost;
    } else if (nid == NID_gost89_cnt) {
        *cipher = &cipher_gost_cpacnt;
    } else {
        ok = 0;
        *cipher = NULL;
    }
    return ok;
}

static int gost_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
                           const int **nids, int nid)
{
    if (!pmeth) {
        *nids = gost_pkey_meth_nids;
        return 3;
    }

    switch (nid) {
    case NID_id_GostR3410_94:
        *pmeth = pmeth_GostR3410_94;
        return 1;
    case NID_id_GostR3410_2001:
        *pmeth = pmeth_GostR3410_2001;
        return 1;
    case NID_id_Gost28147_89_MAC:
        *pmeth = pmeth_Gost28147_MAC;
        return 1;
    default:;
    }

    *pmeth = NULL;
    return 0;
}

static int gost_pkey_asn1_meths(ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth,
                                const int **nids, int nid)
{
    if (!ameth) {
        *nids = gost_pkey_meth_nids;
        return 3;
    }
    switch (nid) {
    case NID_id_GostR3410_94:
        *ameth = ameth_GostR3410_94;
        return 1;
    case NID_id_GostR3410_2001:
        *ameth = ameth_GostR3410_2001;
        return 1;
    case NID_id_Gost28147_89_MAC:
        *ameth = ameth_Gost28147_MAC;
        return 1;

    default:;
    }

    *ameth = NULL;
    return 0;
}

#ifdef OPENSSL_NO_DYNAMIC_ENGINE
static ENGINE *engine_gost(void)
{
    ENGINE *ret = ENGINE_new();
    if (!ret)
        return NULL;
    if (!bind_gost(ret, engine_gost_id)) {
        ENGINE_free(ret);
        return NULL;
    }
    return ret;
}

void ENGINE_load_gost(void)
{
    ENGINE *toadd;
    if (pmeth_GostR3410_94)
        return;
    toadd = engine_gost();
    if (!toadd)
        return;
    ENGINE_add(toadd);
    ENGINE_free(toadd);
    ERR_clear_error();
}
#endif
