Initialise alg.
[openssl.git] / engines / ccgost / gost_ameth.c
index 39a175f52cf057bd1f2debed2b2d863443520266..8b9230b9ab4296054b60d09ef2c760f3c2de77e3 100644 (file)
@@ -7,10 +7,15 @@
  *       for OpenSSL                                                  *
  *          Requires OpenSSL 0.9.9 for compilation                    *
  **********************************************************************/
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
 #include <openssl/engine.h>
 #include <openssl/evp.h>
 #include <openssl/asn1.h>
-#include <string.h>
+#ifndef OPENSSL_NO_CMS
+#include <openssl/cms.h>
+#endif
 #include "gost_params.h"
 #include "gost_lcl.h"
 #include "e_gost_err.h"
@@ -37,7 +42,7 @@ static ASN1_STRING  *encode_gost_algor_params(const EVP_PKEY *key)
        ASN1_STRING *params = ASN1_STRING_new();
        GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new();
        int pkey_param_nid = NID_undef;
-       int cipher_param_nid = NID_undef;
+
        if (!params || !gkp) 
                {
                GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS,
@@ -48,17 +53,8 @@ static ASN1_STRING  *encode_gost_algor_params(const EVP_PKEY *key)
                }       
        switch (EVP_PKEY_base_id(key)) 
                {
-               case NID_id_GostR3410_2001_cc:
-                       pkey_param_nid = NID_id_GostR3410_2001_ParamSet_cc;
-                       cipher_param_nid = NID_id_Gost28147_89_cc;
-                       break;
-               case NID_id_GostR3410_94_cc:
-                       pkey_param_nid = NID_id_GostR3410_94_CryptoPro_A_ParamSet;
-                       cipher_param_nid = NID_id_Gost28147_89_cc;
-                       break;
                case NID_id_GostR3410_2001:
                        pkey_param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)key)));
-                       cipher_param_nid = get_encryption_params(NULL)->nid;
                        break;
                case NID_id_GostR3410_94:
                        pkey_param_nid = (int) gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)key));
@@ -70,7 +66,6 @@ static ASN1_STRING  *encode_gost_algor_params(const EVP_PKEY *key)
                                params=NULL;
                                goto err;
                                }       
-                       cipher_param_nid = get_encryption_params(NULL)->nid;
                        break;
                }       
        gkp->key_params = OBJ_nid2obj(pkey_param_nid);
@@ -128,7 +123,6 @@ static int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg)
        switch (pkey_nid) 
                {
                case NID_id_GostR3410_94:
-               case NID_id_GostR3410_94_cc:
                {
                DSA *dsa= EVP_PKEY_get0(pkey);
                if (!dsa) 
@@ -140,7 +134,6 @@ static int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg)
                break;
                }
                case NID_id_GostR3410_2001:
-               case NID_id_GostR3410_2001_cc:
                {
                EC_KEY *ec = EVP_PKEY_get0(pkey);
                if (!ec) 
@@ -160,7 +153,6 @@ static int gost_set_priv_key(EVP_PKEY *pkey,BIGNUM *priv)
        switch (EVP_PKEY_base_id(pkey)) 
                {
                case NID_id_GostR3410_94:
-               case NID_id_GostR3410_94_cc:
                {
                DSA *dsa = EVP_PKEY_get0(pkey);
                if (!dsa) 
@@ -174,7 +166,6 @@ static int gost_set_priv_key(EVP_PKEY *pkey,BIGNUM *priv)
                break;
                }       
                case NID_id_GostR3410_2001:
-               case NID_id_GostR3410_2001_cc:
                {
                EC_KEY *ec = EVP_PKEY_get0(pkey);
                if (!ec) 
@@ -190,12 +181,11 @@ static int gost_set_priv_key(EVP_PKEY *pkey,BIGNUM *priv)
                }
        return 1;               
        }
-BIGNUM* gost_get_priv_key(const EVP_PKEY *pkey) 
+BIGNUM* gost_get0_priv_key(const EVP_PKEY *pkey) 
        {
        switch (EVP_PKEY_base_id(pkey)) 
                {
                case NID_id_GostR3410_94:
-               case NID_id_GostR3410_94_cc:
                {
                DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pkey);
                if (!dsa) 
@@ -203,11 +193,10 @@ BIGNUM* gost_get_priv_key(const EVP_PKEY *pkey)
                        return NULL;
                        }       
                if (!dsa->priv_key) return NULL;
-               return BN_dup(dsa->priv_key);
+               return dsa->priv_key;
                break;
                }       
                case NID_id_GostR3410_2001:
-               case NID_id_GostR3410_2001_cc:
                {
                EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pkey);
                const BIGNUM* priv;
@@ -216,7 +205,7 @@ BIGNUM* gost_get_priv_key(const EVP_PKEY *pkey)
                        return NULL;
                        }       
                if (!(priv=EC_KEY_get0_private_key(ec))) return NULL;
-               return BN_dup(priv);
+               return (BIGNUM *)priv;
                break;
                }
                }
@@ -244,6 +233,24 @@ static int pkey_ctrl_gost(EVP_PKEY *pkey, int op,
                                X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0);
                                }
                        return 1;
+#ifndef OPENSSL_NO_CMS
+               case ASN1_PKEY_CTRL_CMS_SIGN:
+                       if (arg1 == 0) 
+                               {
+                               X509_ALGOR *alg1 = NULL, *alg2 = NULL;
+                               int nid = EVP_PKEY_base_id(pkey);
+                               CMS_SignerInfo_get0_algs((CMS_SignerInfo *)arg2, 
+                                       NULL, NULL, &alg1, &alg2);
+                               X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94),
+                                       V_ASN1_NULL, 0);
+                               if (nid == NID_undef) 
+                                       {
+                                       return (-1);
+                                       }
+                               X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0);
+                               }
+                       return 1;
+#endif
                case ASN1_PKEY_CTRL_PKCS7_ENCRYPT:
                        if (arg1 == 0)
                                {
@@ -258,6 +265,22 @@ static int pkey_ctrl_gost(EVP_PKEY *pkey, int op,
                                        V_ASN1_SEQUENCE, params);
                                }
                        return 1;
+#ifndef OPENSSL_NO_CMS
+               case ASN1_PKEY_CTRL_CMS_ENVELOPE:
+                       if (arg1 == 0)
+                               {
+                               X509_ALGOR *alg = NULL;
+                               ASN1_STRING * params = encode_gost_algor_params(pkey);
+                               if (!params) 
+                                       {
+                                       return -1;
+                                       }
+                               CMS_RecipientInfo_ktri_get0_algs((CMS_RecipientInfo *)arg2, NULL, NULL, &alg);
+                               X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type),
+                                       V_ASN1_SEQUENCE, params);
+                               }
+                       return 1;
+#endif
                case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
                        *(int *)arg2 = NID_id_GostR3411_94;
                        return 2;
@@ -308,7 +331,7 @@ static int priv_decode_gost( EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf)
                ASN1_OCTET_STRING *s = d2i_ASN1_OCTET_STRING(NULL,&p,priv_len);
                if (!s||s->length !=32) 
                        {
-                       GOSTerr(GOST_F_PRIV_DECODE_GOST_94,
+                       GOSTerr(GOST_F_PRIV_DECODE_GOST,
                                EVP_R_DECODE_ERROR);
                        return 0;       
                        }
@@ -322,9 +345,12 @@ static int priv_decode_gost( EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf)
        else
                {
                priv_key=d2i_ASN1_INTEGER(NULL,&p,priv_len);
-               if (!priv_key || !(pk_num =  ASN1_INTEGER_to_BN(priv_key, NULL))) 
+               if (!priv_key) return 0;
+               ret= ((pk_num =  ASN1_INTEGER_to_BN(priv_key, NULL))!=NULL) ;
+               ASN1_INTEGER_free(priv_key);
+               if (!ret)
                        {
-                       GOSTerr(GOST_F_PRIV_DECODE_GOST_94,
+                       GOSTerr(GOST_F_PRIV_DECODE_GOST,
                                EVP_R_DECODE_ERROR);
                        return 0;       
                        }
@@ -342,34 +368,145 @@ static int priv_encode_gost(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk)
        ASN1_STRING *params = encode_gost_algor_params(pk);
        unsigned char *priv_buf = NULL;
        int priv_len;
-       BIGNUM *key;
 
        ASN1_INTEGER *asn1key=NULL;
        if (!params) 
                {
                return 0;
                }
-       key = gost_get_priv_key(pk);
-       asn1key = BN_to_ASN1_INTEGER(key,NULL);
-       BN_free(key);
+       asn1key = BN_to_ASN1_INTEGER(gost_get0_priv_key(pk),NULL);
        priv_len = i2d_ASN1_INTEGER(asn1key,&priv_buf);
        ASN1_INTEGER_free(asn1key);
        return PKCS8_pkey_set0(p8,algobj,0,V_ASN1_SEQUENCE,params,
                priv_buf,priv_len);
        }
+/* --------- printing keys --------------------------------*/
+static int print_gost_94(BIO *out, const EVP_PKEY *pkey, int indent,
+       ASN1_PCTX *pctx, int type) 
+       {
+       int param_nid = NID_undef;
+
+       if (type == 2) 
+               {
+               BIGNUM *key;
+
+               if (!BIO_indent(out,indent,128)) return 0;
+               BIO_printf(out,"Private key: ");
+               key = gost_get0_priv_key(pkey);
+               if (!key) 
+                       BIO_printf(out,"<undefined>");
+               else 
+                       BN_print(out,key);
+               BIO_printf(out,"\n");
+               }
+       if (type >= 1)
+               {
+               BIGNUM *pubkey;
+               
+               pubkey = ((DSA *)EVP_PKEY_get0((EVP_PKEY *)pkey))->pub_key;
+               BIO_indent(out,indent,128);
+               BIO_printf(out,"Public key: ");
+               BN_print(out,pubkey);
+               BIO_printf(out,"\n");
+       }       
+
+       param_nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey));
+       BIO_indent(out,indent,128);
+       BIO_printf(out, "Parameter set: %s\n",OBJ_nid2ln(param_nid));
+       return 1;
+}
 
-static int priv_print_gost (BIO *out,const EVP_PKEY *pkey, int indent,
+static int param_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent,
        ASN1_PCTX *pctx) 
        {
-       BIGNUM *key;
+       return print_gost_94(out, pkey, indent, pctx,0);
+       }
+
+static int pub_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent,
+       ASN1_PCTX *pctx)
+       {
+       return print_gost_94(out,pkey, indent, pctx,1);
+       }
+static int priv_print_gost94(BIO *out,const EVP_PKEY *pkey, int indent,
+       ASN1_PCTX *pctx) 
+       {
+       return print_gost_94(out,pkey,indent,pctx,2);
+       }
+
+static int print_gost_01(BIO *out, const EVP_PKEY *pkey, int indent,
+       ASN1_PCTX *pctx, int type)
+       {
+       int param_nid = NID_undef;
+       if (type == 2) 
+               {
+               BIGNUM *key;
+
+               if (!BIO_indent(out,indent,128)) return 0;
+               BIO_printf(out,"Private key: ");
+               key = gost_get0_priv_key(pkey);
+               if (!key) 
+                       BIO_printf(out,"<undefined)");
+               else 
+                       BN_print(out,key);
+               BIO_printf(out,"\n");
+               }
+       if (type >= 1) 
+               {
+               BN_CTX *ctx = BN_CTX_new();
+               BIGNUM *X,*Y;
+               const EC_POINT *pubkey;
+               const EC_GROUP *group;
+
+               if (!ctx) 
+                       {
+                       GOSTerr(GOST_F_PRINT_GOST_01,ERR_R_MALLOC_FAILURE);
+                       return 0;
+                       }
+               BN_CTX_start(ctx);
+               X = BN_CTX_get(ctx);
+               Y = BN_CTX_get(ctx);
+               pubkey = EC_KEY_get0_public_key((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey));
+               group = EC_KEY_get0_group((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey));
+               if (!EC_POINT_get_affine_coordinates_GFp(group,pubkey,X,Y,ctx)) 
+                       {
+                       GOSTerr(GOST_F_PRINT_GOST_01,ERR_R_EC_LIB);
+                       BN_CTX_free(ctx);
+                       return 0;
+                       }
+               if (!BIO_indent(out,indent,128)) return 0;
+               BIO_printf(out,"Public key:\n");
+               if (!BIO_indent(out,indent+3,128)) return 0;
+               BIO_printf(out,"X:");
+               BN_print(out,X);
+               BIO_printf(out,"\n");
+               BIO_indent(out,indent+3,128);
+               BIO_printf(out,"Y:");
+               BN_print(out,Y);
+               BIO_printf(out,"\n");
+               BN_CTX_end(ctx);
+               BN_CTX_free(ctx);
+               }
+
+       param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey)));
        if (!BIO_indent(out,indent,128)) return 0;
-       key = gost_get_priv_key(pkey);
-       if (!key) return 0;
-       BN_print(out,key);
-       BN_free(key);
+       BIO_printf(out,"Parameter set: %s\n",OBJ_nid2ln(param_nid));
        return 1;
+}
+static int param_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent,
+       ASN1_PCTX *pctx) 
+       {       
+       return print_gost_01(out,pkey,indent,pctx,0);
+       }
+static int pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent,
+       ASN1_PCTX *pctx)
+       {
+       return print_gost_01(out,pkey, indent, pctx,1);
+       }
+static int priv_print_gost01(BIO *out,const EVP_PKEY *pkey, int indent,
+       ASN1_PCTX *pctx) 
+       {
+       return print_gost_01(out,pkey,indent,pctx,2);
        }
-
 /* ---------------------------------------------------------------------*/
 static int param_missing_gost94(const EVP_PKEY *pk) 
        {
@@ -429,7 +566,7 @@ static int param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from)
                }       
        if (!efrom) 
                {
-               GOSTerr(GOST_F_PARAM_COPY_GOST94,
+               GOSTerr(GOST_F_PARAM_COPY_GOST01,
                        GOST_R_KEY_PARAMETERS_MISSING);
                return 0;
                }       
@@ -438,7 +575,7 @@ static int param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from)
                eto = EC_KEY_new();
                EVP_PKEY_assign(to,EVP_PKEY_base_id(from),eto);
                }       
-       EC_KEY_set_group(eto,EC_GROUP_dup(EC_KEY_get0_group(efrom)));
+       EC_KEY_set_group(eto,EC_KEY_get0_group(efrom));
        if (EC_KEY_get0_private_key(eto)) 
                {
                gost2001_compute_public(eto);
@@ -543,6 +680,7 @@ static int pub_decode_gost01(EVP_PKEY *pk,X509_PUBKEY *pub)
        EC_POINT *pub_key;
        BIGNUM *X,*Y;
        ASN1_OCTET_STRING *octet= NULL;
+       int len;
        const EC_GROUP *group;
 
        if (!X509_PUBKEY_get0_param(&palgobj,&pubkey_buf,&pub_len,
@@ -553,7 +691,7 @@ static int pub_decode_gost01(EVP_PKEY *pk,X509_PUBKEY *pub)
        octet = d2i_ASN1_OCTET_STRING(NULL,&pubkey_buf,pub_len);
        if (!octet) 
                {
-               GOSTerr(GOST_F_PUB_DECODE_GOST94,ERR_R_MALLOC_FAILURE);
+               GOSTerr(GOST_F_PUB_DECODE_GOST01,ERR_R_MALLOC_FAILURE);
                return 0;
                }       
        databuf = OPENSSL_malloc(octet->length);
@@ -561,16 +699,11 @@ static int pub_decode_gost01(EVP_PKEY *pk,X509_PUBKEY *pub)
                {
                databuf[j]=octet->data[i];
                }
-       if (EVP_PKEY_base_id(pk) == NID_id_GostR3410_2001_cc) 
-               {
-               X= getbnfrombuf(databuf,octet->length/2);
-               Y= getbnfrombuf(databuf+(octet->length/2),octet->length/2);
-               }
-       else 
-               {
-               Y= getbnfrombuf(databuf,octet->length/2);
-               X= getbnfrombuf(databuf+(octet->length/2),octet->length/2);
-               }
+       len=octet->length/2;
+       ASN1_OCTET_STRING_free(octet);  
+       
+       Y= getbnfrombuf(databuf,len);
+       X= getbnfrombuf(databuf+len,len);
        OPENSSL_free(databuf);
        pub_key = EC_POINT_new(group);
        if (!EC_POINT_set_affine_coordinates_GFp(group
@@ -578,6 +711,9 @@ static int pub_decode_gost01(EVP_PKEY *pk,X509_PUBKEY *pub)
                {
                GOSTerr(GOST_F_PUB_DECODE_GOST01,
                        ERR_R_EC_LIB);
+               EC_POINT_free(pub_key);
+               BN_free(X);
+               BN_free(Y);
                return 0;
                }       
        BN_free(X);
@@ -586,9 +722,10 @@ static int pub_decode_gost01(EVP_PKEY *pk,X509_PUBKEY *pub)
                {
                GOSTerr(GOST_F_PUB_DECODE_GOST01,
                        ERR_R_EC_LIB);
+               EC_POINT_free(pub_key);
                return 0;
                }       
-       /*EC_POINT_free(pub_key);*/
+       EC_POINT_free(pub_key);
        return 1;
 
        }
@@ -629,16 +766,10 @@ static int pub_encode_gost01(X509_PUBKEY *pub,const EVP_PKEY *pk)
        BN_free(order);
        databuf = OPENSSL_malloc(data_len);
        memset(databuf,0,data_len);
-       if (EVP_PKEY_base_id(pk) == NID_id_GostR3410_2001_cc) 
-               {
-               store_bignum(X,databuf,data_len/2);
-               store_bignum(Y,databuf+data_len/2,data_len/2);
-               }
-       else 
-               {
-               store_bignum(X,databuf+data_len/2,data_len/2);
-               store_bignum(Y,databuf,data_len/2);
-               }
+       
+       store_bignum(X,databuf+data_len/2,data_len/2);
+       store_bignum(Y,databuf,data_len/2);
+
        BN_free(X);
        BN_free(Y);
        octet = ASN1_OCTET_STRING_new();
@@ -681,22 +812,8 @@ static int pub_cmp_gost01(const EVP_PKEY *a,const EVP_PKEY *b)
        return ret;
        }
 
-static int pub_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent,
-       ASN1_PCTX *pctx)
-       {
-       const BIGNUM *key;
-       if (!BIO_indent(out,indent,128)) return 0;
-       key = ((DSA *)EVP_PKEY_get0((EVP_PKEY *)pkey))->pub_key;
-       if (!key) return 0;
-       BN_print(out,key);
-       return 1;
-       }
 
-static int pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent,
-       ASN1_PCTX *pctx)
-       {
-       return 0;
-       }
+
 
 static int pkey_size_gost(const EVP_PKEY *pk)
        {
@@ -719,11 +836,64 @@ static int mac_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2)
        switch (op)
                {
                case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
-                       *(int *)arg2 = NID_undef;
+                       *(int *)arg2 = NID_id_Gost28147_89_MAC;
                        return 2;
                }
        return -2;
 }      
+
+static int gost94_param_encode(const EVP_PKEY *pkey, unsigned char **pder) 
+{
+   int nid=gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey));
+   return i2d_ASN1_OBJECT(OBJ_nid2obj(nid),pder);
+}
+static int gost2001_param_encode(const EVP_PKEY *pkey, unsigned char **pder) 
+{
+   int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey)));
+   return i2d_ASN1_OBJECT(OBJ_nid2obj(nid),pder);
+}
+
+static int gost94_param_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen)
+{
+       ASN1_OBJECT *obj=NULL;
+       DSA *dsa = EVP_PKEY_get0(pkey);
+       int nid;
+       if (d2i_ASN1_OBJECT(&obj,pder,derlen)==NULL) {
+               return 0;
+       }
+       nid = OBJ_obj2nid(obj);
+       ASN1_OBJECT_free(obj);
+       if (!dsa) 
+               {
+               dsa=DSA_new();
+               if (!EVP_PKEY_assign(pkey,NID_id_GostR3410_94,dsa)) return 0;
+               }
+       if (!fill_GOST94_params(dsa,nid)) return 0;
+       return 1;
+}      
+
+static int gost2001_param_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen) {
+       ASN1_OBJECT *obj=NULL;
+       int nid;
+       EC_KEY *ec = EVP_PKEY_get0(pkey);
+       if (d2i_ASN1_OBJECT(&obj,pder,derlen)==NULL) {
+               return 0;
+       }
+       nid = OBJ_obj2nid(obj);
+       ASN1_OBJECT_free(obj);
+       if (!ec) 
+               {
+               ec = EC_KEY_new();
+               if (!EVP_PKEY_assign(pkey,NID_id_GostR3410_2001,ec)) return 0;
+               }       
+       if (!fill_GOST2001_params(ec, nid)) return 0;
+       return 1;
+}      
+
+
+
+
+
 /* ----------------------------------------------------------------------*/
 int register_ameth_gost (int nid, EVP_PKEY_ASN1_METHOD **ameth, const char* pemstr, const char* info) 
        {
@@ -732,16 +902,16 @@ int register_ameth_gost (int nid, EVP_PKEY_ASN1_METHOD **ameth, const char* pems
        if (!*ameth) return 0;
        switch (nid) 
                {
-               case NID_id_GostR3410_94_cc:
                case NID_id_GostR3410_94:
                        EVP_PKEY_asn1_set_free (*ameth, pkey_free_gost94);
                        EVP_PKEY_asn1_set_private (*ameth, 
                                priv_decode_gost, priv_encode_gost, 
-                               priv_print_gost);
+                               priv_print_gost94);
 
-                       EVP_PKEY_asn1_set_param (*ameth, 0, 0,
+                       EVP_PKEY_asn1_set_param (*ameth, 
+                               gost94_param_decode, gost94_param_encode,
                                param_missing_gost94, param_copy_gost94, 
-                               param_cmp_gost94,0 );
+                               param_cmp_gost94,param_print_gost94 );
                        EVP_PKEY_asn1_set_public (*ameth,
                                pub_decode_gost94, pub_encode_gost94,
                                pub_cmp_gost94, pub_print_gost94,
@@ -749,16 +919,16 @@ int register_ameth_gost (int nid, EVP_PKEY_ASN1_METHOD **ameth, const char* pems
        
                        EVP_PKEY_asn1_set_ctrl (*ameth, pkey_ctrl_gost);
                        break;
-               case NID_id_GostR3410_2001_cc:
                case NID_id_GostR3410_2001:
                        EVP_PKEY_asn1_set_free (*ameth, pkey_free_gost01);
                        EVP_PKEY_asn1_set_private (*ameth, 
                                priv_decode_gost, priv_encode_gost, 
-                               priv_print_gost);
+                               priv_print_gost01);
 
-                       EVP_PKEY_asn1_set_param (*ameth, 0, 0,
+                       EVP_PKEY_asn1_set_param (*ameth, 
+                               gost2001_param_decode, gost2001_param_encode,
                                param_missing_gost01, param_copy_gost01, 
-                               param_cmp_gost01, 0);
+                               param_cmp_gost01, param_print_gost01);
                        EVP_PKEY_asn1_set_public (*ameth,
                                pub_decode_gost01, pub_encode_gost01,
                                pub_cmp_gost01, pub_print_gost01,