Don't load GOST ENGINE if it is already loaded.
[openssl.git] / engines / ccgost / gost_eng.c
index feb2a1f61551e097cb71fc9ef25165af126145c1..ebf0b625b5b316aba7b0f38f4ebe833d10f04f83 100644 (file)
@@ -8,6 +8,8 @@
  *          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>
@@ -31,20 +33,22 @@ 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, 0};
+    {NID_id_Gost28147_89, NID_gost89_cnt,0};
 
 static int gost_digest_nids[] =
-       {NID_id_GostR3411_94, 0};
+       {NID_id_GostR3411_94,NID_id_Gost28147_89_MAC, 0};
 
 static int gost_pkey_meth_nids[] = 
-       {NID_id_GostR3410_94_cc, NID_id_GostR3410_94, NID_id_GostR3410_2001_cc,
-        NID_id_GostR3410_2001, 0};
+       {NID_id_GostR3410_94,
+        NID_id_GostR3410_2001, NID_id_Gost28147_89_MAC, 0};
 
-static EVP_PKEY_METHOD *pmeth_GostR3410_94_cc = NULL, *pmeth_GostR3410_94 = NULL,
-       *pmeth_GostR3410_2001_cc = NULL, *pmeth_GostR3410_2001 = NULL;
+static EVP_PKEY_METHOD *pmeth_GostR3410_94 = NULL,
+        *pmeth_GostR3410_2001 = NULL,
+       *pmeth_Gost28147_MAC = NULL;
 
-static EVP_PKEY_ASN1_METHOD *ameth_GostR3410_94_cc = NULL, *ameth_GostR3410_94 = NULL,
-       *ameth_GostR3410_2001_cc = NULL, *ameth_GostR3410_2001 = 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)
@@ -59,6 +63,14 @@ static int gost_engine_finish(ENGINE *e)
 
 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;
        }
 
@@ -115,21 +127,23 @@ static int bind_gost (ENGINE *e,const char *id)
                goto end;
                }
 
-       if (!register_ameth_gost(NID_id_GostR3410_94_cc, &ameth_GostR3410_94_cc, "GOST94CC", "GOST R 34.10-94, Cryptocom LTD implementation")) 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_cc, &ameth_GostR3410_2001_cc, "GOST2001CC", "GOST R 34.10-2001, Cryptocom LTD implementation")) 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_cc, &pmeth_GostR3410_94_cc, 0)) goto end;
        if (!register_pmeth_gost(NID_id_GostR3410_94, &pmeth_GostR3410_94, 0)) goto end;
-       if (!register_pmeth_gost(NID_id_GostR3410_2001_cc, &pmeth_GostR3410_2001_cc, 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;
@@ -141,20 +155,10 @@ static int bind_gost (ENGINE *e,const char *id)
        return ret;
        }       
 
-#ifdef _WIN32
-extern __declspec( dllexport ) 
-#endif
-       
-//#ifndef OPENSSL_NO_DYNAMIC_ENGINE
-IMPLEMENT_DYNAMIC_BIND_FN(bind_gost);
-
-#ifdef _WIN32
-extern __declspec( dllexport ) 
-#endif
-
-IMPLEMENT_DYNAMIC_CHECK_FN();
-//#else
-//#endif /* OPENSSL_NO_DYNAMIC_ENGINE */
+#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)
@@ -163,14 +167,18 @@ static int gost_digests(ENGINE *e, const EVP_MD **digest,
        if (!digest) 
                {
                *nids = gost_digest_nids;
-               return 1
+               return 2
                }
-       //printf("Digest no %d requested\n",nid);
+       /*printf("Digest no %d requested\n",nid);*/
        if(nid == NID_id_GostR3411_94) 
                {
                *digest = &digest_gost;
                }
-       else 
+       else if (nid == NID_id_Gost28147_89_MAC) 
+               {
+               *digest = &imit_gost_cpa;
+               }
+       else
                {
                ok =0;
                *digest = NULL;
@@ -185,14 +193,18 @@ static int gost_ciphers (ENGINE *e,const EVP_CIPHER **cipher,
        if (!cipher) 
                {
                *nids = gost_cipher_nids;
-               return 1; /* Only one cipher supported */
+               return 2; /* two ciphers are supported */
                }
 
        if(nid == NID_id_Gost28147_89) 
                {
                *cipher = &cipher_gost;
                }
-       else 
+       else if  (nid == NID_gost89_cnt) 
+               {
+               *cipher = &cipher_gost_cpacnt;
+               }
+       else    
                {
                ok = 0;
                *cipher = NULL;
@@ -206,15 +218,14 @@ static int gost_pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth,
        if (!pmeth) 
                {
                *nids = gost_pkey_meth_nids;
-               return 4;
+               return 3;
                }
 
        switch (nid) 
                {
-               case NID_id_GostR3410_94_cc: *pmeth = pmeth_GostR3410_94_cc; return 1;
                case NID_id_GostR3410_94: *pmeth = pmeth_GostR3410_94; return 1;
-               case NID_id_GostR3410_2001_cc: *pmeth = pmeth_GostR3410_2001_cc; 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:;
                }
        
@@ -228,14 +239,14 @@ static int gost_pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth,
        if (!ameth) 
                {
                *nids = gost_pkey_meth_nids;
-               return 4;
+               return 3;
                }
        switch (nid) 
                {
-               case NID_id_GostR3410_94_cc: *ameth = ameth_GostR3410_94_cc; return 1;
                case NID_id_GostR3410_94: *ameth = ameth_GostR3410_94; return 1;
-               case NID_id_GostR3410_2001_cc: *ameth = ameth_GostR3410_2001_cc; 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:;
                }
        
@@ -259,7 +270,10 @@ static ENGINE *engine_gost(void)
        
 void ENGINE_load_gost(void)
        {
-       ENGINE *toadd =engine_gost();
+       ENGINE *toadd;
+       if (pmeth_GostR3410_94)
+               return;
+       toadd = engine_gost();
        if (!toadd) return;
        ENGINE_add(toadd);
        ENGINE_free(toadd);