We strictly need use our custom paramsets for GOST algorithms (all of cipher, 
hash and signature,
including X509 and TLS). If most of the functionality may be implemented by 
"dirty" overriding
initialization methods, X509 requires ccgost engine sources patching.

Seems 2 ways:
1. Put our paramsets into ccgost sources and simple support for several 
paramsets in ASN1 hash
params serializing.
2. Allow set any paramset from outside.

First way seems the simplest, but second - more universal and useful.

Our current implementation for second way (see attached patch) requires ccgost 
engine directly
using, not only through high-level APIs.

Example of usage for X509 (GOST 28147-89, GOST R 34.10-2001 and GOST R 
34.11-94, with one paramset
for cipher and hash):

1. Add custom paramsets to chains:

  gost2001_paramset_append( gost2001_custom_paramset );
  gost_cipher_list_append( gost89_custom_paramset );

2. Make private key for certificate:

  EC_KEY *ec( EC_KEY_new() );
  BN_CTX *ctx( BN_CTX_new() );
  BN_CTX_start( ctx );
  EC_GROUP *grp( EC_GROUP_new_curve_GFp( gost2001_custom_paramset->p, 
gost2001_custom_paramset->a,
gost2001_custom_paramset->b, ctx ) );
  EC_GROUP_set_curve_name( grp, NID_id_GostR3410_2001_DrWebParamSet );
  EC_POINT *P( EC_POINT_new( grp ) );
  EC_POINT_set_affine_coordinates_GFp( grp, P, gost2001_custom_paramset->x,
gost2001_custom_paramset->y, ctx );
  EC_GROUP_set_generator( grp, P, gost2001_custom_paramset->q, 0 );
  EC_KEY_set_group( ec, grp );
  BN_CTX_end( ctx );

  EVP_PKEY *pkey( EVP_PKEY_new() );
  EVP_PKEY_assign( pkey, NID_id_GostR3410_2001, ec );

  GOST3410_EX_DATA *ex_data = GOST3410_get_ex_data( pkey );
  ex_data->hash_params_nid = NID_id_Gost28147_89_DrWebParamSet;
  ex_data->cipher_params_nid = NID_id_Gost28147_89_DrWebParamSet;

Can this feature be useful for the community? And which way seems be more 
useful?
-- 
With best regards, Arseniy Ankudinov
Software Engineer, Doctor Web Ltd

You deleted an attachment from this message. The original MIME headers for the attachment were:
Content-Type: text/x-patch;
 name="tls_gost_custom_paramsets.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="tls_gost_custom_paramsets.patch"


diff -Naur --no-dereference openssl-1.0.2d/crypto/crypto.h openssl-1.0.2d.new/crypto/crypto.h
--- openssl-1.0.2d/crypto/crypto.h	2015-07-09 11:53:21.000000000 +0000
+++ openssl-1.0.2d.new/crypto/crypto.h	2015-08-07 06:09:44.000000000 +0000
@@ -332,6 +332,7 @@
 # define CRYPTO_EX_INDEX_ECDH            13
 # define CRYPTO_EX_INDEX_COMP            14
 # define CRYPTO_EX_INDEX_STORE           15
+# define CRYPTO_EX_INDEX_GOST3410        16
 
 /*
  * Dynamically assigned indexes start from this value (don't use directly,
diff -Naur --no-dereference openssl-1.0.2d/engines/ccgost/Makefile openssl-1.0.2d.new/engines/ccgost/Makefile
--- openssl-1.0.2d/engines/ccgost/Makefile	2015-07-09 12:03:07.000000000 +0000
+++ openssl-1.0.2d.new/engines/ccgost/Makefile	2015-08-07 06:09:44.000000000 +0000
@@ -8,9 +8,9 @@
 CFLAGS= $(INCLUDES) $(CFLAG)
 LIB=$(TOP)/libcrypto.a
 
-LIBSRC= gost2001.c gost2001_keyx.c gost89.c gost94_keyx.c gost_ameth.c gost_asn1.c gost_crypt.c gost_ctl.c gost_eng.c gosthash.c gost_keywrap.c gost_md.c gost_params.c gost_pmeth.c gost_sign.c
+LIBSRC= gost2001.c gost2001_keyx.c gost89.c gost94_keyx.c gost_ameth.c gost_asn1.c gost_crypt.c gost_ctl.c gost_eng.c gosthash.c gost_keywrap.c gost_lib.c gost_md.c gost_params.c gost_pmeth.c gost_sign.c
 
-LIBOBJ= e_gost_err.o gost2001_keyx.o gost2001.o gost89.o gost94_keyx.o gost_ameth.o gost_asn1.o gost_crypt.o gost_ctl.o gost_eng.o gosthash.o gost_keywrap.o gost_md.o gost_params.o gost_pmeth.o gost_sign.o
+LIBOBJ= e_gost_err.o gost2001_keyx.o gost2001.o gost89.o gost94_keyx.o gost_ameth.o gost_asn1.o gost_crypt.o gost_ctl.o gost_eng.o gosthash.o gost_keywrap.o gost_lib.o gost_md.o gost_params.o gost_pmeth.o gost_sign.o
 
 SRC=$(LIBSRC)
 
@@ -274,3 +274,4 @@
 gost_sign.o: e_gost_err.h gost89.h gost_lcl.h gost_params.h gost_sign.c
 gost_sign.o: gosthash.h
 gosthash.o: gost89.h gosthash.c gosthash.h
+gost_lib.o: e_gost_err.h gost89.h gost_lcl.h gost_lib.c gosthash.h
diff -Naur --no-dereference openssl-1.0.2d/engines/ccgost/e_gost_err.c openssl-1.0.2d.new/engines/ccgost/e_gost_err.c
--- openssl-1.0.2d/engines/ccgost/e_gost_err.c	2015-07-09 11:53:21.000000000 +0000
+++ openssl-1.0.2d.new/engines/ccgost/e_gost_err.c	2015-08-07 06:09:44.000000000 +0000
@@ -115,6 +115,8 @@
     {ERR_FUNC(GOST_F_PUB_ENCODE_GOST01), "PUB_ENCODE_GOST01"},
     {ERR_FUNC(GOST_F_UNPACK_CC_SIGNATURE), "UNPACK_CC_SIGNATURE"},
     {ERR_FUNC(GOST_F_UNPACK_CP_SIGNATURE), "UNPACK_CP_SIGNATURE"},
+    {ERR_FUNC(GOST_F_ECGOST_DATA_NEW_METHOD), "ECGOST_DATA_NEW_METHOD"},
+    {ERR_FUNC(GOST_F_GOST3410_EX_DATA_NEW_METHOD), "GOST3410_EX_DATA_NEW_METHOD"},
     {0, NULL}
 };
 
diff -Naur --no-dereference openssl-1.0.2d/engines/ccgost/e_gost_err.h openssl-1.0.2d.new/engines/ccgost/e_gost_err.h
--- openssl-1.0.2d/engines/ccgost/e_gost_err.h	2015-07-09 11:53:21.000000000 +0000
+++ openssl-1.0.2d.new/engines/ccgost/e_gost_err.h	2015-08-07 06:09:44.000000000 +0000
@@ -115,6 +115,8 @@
 # define GOST_F_PUB_ENCODE_GOST01                         135
 # define GOST_F_UNPACK_CC_SIGNATURE                       136
 # define GOST_F_UNPACK_CP_SIGNATURE                       137
+# define GOST_F_ECGOST_DATA_NEW_METHOD                    138
+# define GOST_F_GOST3410_EX_DATA_NEW_METHOD               139
 
 /* Reason codes. */
 # define GOST_R_BAD_KEY_PARAMETERS_FORMAT                 99
diff -Naur --no-dereference openssl-1.0.2d/engines/ccgost/gost2001.c openssl-1.0.2d.new/engines/ccgost/gost2001.c
--- openssl-1.0.2d/engines/ccgost/gost2001.c	2015-07-09 11:53:21.000000000 +0000
+++ openssl-1.0.2d.new/engines/ccgost/gost2001.c	2015-08-07 06:09:44.000000000 +0000
@@ -57,9 +57,9 @@
         GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_MALLOC_FAILURE);
         goto err;
     }
-    while (params->nid != NID_undef && params->nid != nid)
-        params++;
-    if (params->nid == NID_undef) {
+    while (params->next != NULL && params->nid != nid)
+      params = params->next;
+    if (params == NULL) {
         GOSTerr(GOST_F_FILL_GOST2001_PARAMS,
                 GOST_R_UNSUPPORTED_PARAMETER_SET);
         goto err;
@@ -464,3 +464,10 @@
     BN_free(order);
     return gost2001_compute_public(ec);
 }
+
+void gost2001_paramset_append(struct R3410_2001 *param)
+{
+    struct R3410_2001 *p;
+    for (p=R3410_2001_paramset; p->next; p=p->next);
+    p->next = param;
+}
diff -Naur --no-dereference openssl-1.0.2d/engines/ccgost/gost2001_keyx.c openssl-1.0.2d.new/engines/ccgost/gost2001_keyx.c
--- openssl-1.0.2d/engines/ccgost/gost2001_keyx.c	2015-07-09 11:53:21.000000000 +0000
+++ openssl-1.0.2d.new/engines/ccgost/gost2001_keyx.c	2015-08-07 06:09:44.000000000 +0000
@@ -20,7 +20,7 @@
 
 /* Implementation of CryptoPro VKO 34.10-2001 algorithm */
 static int VKO_compute_key(unsigned char *shared_key, size_t shared_key_size,
-                           const EC_POINT *pub_key, EC_KEY *priv_key,
+                           EVP_PKEY *peer_key, EC_KEY *priv_key,
                            const unsigned char *ukm)
 {
     unsigned char ukm_be[8], databuf[64], hashbuf[64];
@@ -30,6 +30,8 @@
     int i;
     gost_hash_ctx hash_ctx;
     BN_CTX *ctx = BN_CTX_new();
+    const EC_POINT *pub_key = EC_KEY_get0_public_key(EVP_PKEY_get0(peer_key));
+    GOST3410_EX_DATA *ex_data = (GOST3410_EX_DATA *)GOST3410_get_ex_data(peer_key);
 
     for (i = 0; i < 8; i++) {
         ukm_be[7 - i] = ukm[i];
@@ -54,7 +56,9 @@
     for (i = 0; i < 64; i++) {
         hashbuf[63 - i] = databuf[i];
     }
-    init_gost_hash_ctx(&hash_ctx, &GostR3411_94_CryptoProParamSet);
+    init_gost_hash_ctx(&hash_ctx, get_encryption_params(OBJ_nid2obj(ex_data == NULL || ex_data->hash_params_nid == NID_undef
+        ? NID_id_GostR3411_94_CryptoProParamSet
+        : ex_data->hash_params_nid))->sblock);
     start_hash(&hash_ctx);
     hash_block(&hash_ctx, hashbuf, 64);
     finish_hash(&hash_ctx, shared_key);
@@ -93,7 +97,7 @@
 
     *keylen =
         VKO_compute_key(key, 32,
-                        EC_KEY_get0_public_key(EVP_PKEY_get0(peer_key)),
+                        peer_key,
                         (EC_KEY *)EVP_PKEY_get0(my_key), data->shared_ukm);
     return 1;
 }
@@ -125,6 +129,7 @@
     int key_is_ephemeral = 1;
     gost_ctx cctx;
     EVP_PKEY *sec_key = EVP_PKEY_CTX_get0_peerkey(pctx);
+    GOST3410_EX_DATA *ex_data = (GOST3410_EX_DATA *)GOST3410_get_ex_data(pubk);
     if (data->shared_ukm) {
         memcpy(ukm, data->shared_ukm, 8);
     } else if (out) {
@@ -154,13 +159,16 @@
             }
         }
     }
+    if (ex_data != NULL && ex_data->cipher_params_nid != NID_undef) {
+      param = get_encryption_params(OBJ_nid2obj(ex_data->cipher_params_nid));
+    }
     if (!get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS)
         && param == gost_cipher_list) {
         param = gost_cipher_list + 1;
     }
     if (out) {
         VKO_compute_key(shared_key, 32,
-                        EC_KEY_get0_public_key(EVP_PKEY_get0(pubk)),
+                        pubk,
                         EVP_PKEY_get0(sec_key), ukm);
         gost_init(&cctx, param->sblock);
         keyWrapCryptoPro(&cctx, shared_key, ukm, key, crypted_key);
@@ -274,7 +282,7 @@
     OPENSSL_assert(gkt->key_info->imit->length == 4);
     memcpy(wrappedKey + 40, gkt->key_info->imit->data, 4);
     VKO_compute_key(sharedKey, 32,
-                    EC_KEY_get0_public_key(EVP_PKEY_get0(peerkey)),
+                    peerkey,
                     EVP_PKEY_get0(priv), wrappedKey);
     if (!keyUnwrapCryptoPro(&ctx, sharedKey, wrappedKey, key)) {
         GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT,
diff -Naur --no-dereference openssl-1.0.2d/engines/ccgost/gost94_keyx.c openssl-1.0.2d.new/engines/ccgost/gost94_keyx.c
--- openssl-1.0.2d/engines/ccgost/gost94_keyx.c	2015-07-09 11:53:21.000000000 +0000
+++ openssl-1.0.2d.new/engines/ccgost/gost94_keyx.c	2015-08-07 06:09:44.000000000 +0000
@@ -47,30 +47,33 @@
 /*
  * Computes 256 bit Key exchange key as specified in RFC 4357
  */
-static int make_cp_exchange_key(BIGNUM *priv_key, EVP_PKEY *pubk,
-                                unsigned char *shared_key)
+static int make_cp_exchange_key(EVP_PKEY *peer_key, EVP_PKEY *pubk, unsigned char *shared_key)
 {
-    unsigned char dh_key[128];
+    unsigned char dh_key [128];
     int ret;
     gost_hash_ctx hash_ctx;
     DH *dh = DH_new();
+    BIGNUM *priv_key = gost_get0_priv_key(peer_key);
+    GOST3410_EX_DATA *ex_data = (GOST3410_EX_DATA *)GOST3410_get_ex_data(peer_key);
 
     if (!dh)
-        return 0;
+      return 0;
     memset(dh_key, 0, 128);
     dh->g = BN_dup(pubk->pkey.dsa->g);
     dh->p = BN_dup(pubk->pkey.dsa->p);
     dh->priv_key = BN_dup(priv_key);
     ret =
-        compute_pair_key_le(dh_key, ((DSA *)(EVP_PKEY_get0(pubk)))->pub_key,
-                            dh);
+        compute_pair_key_le(dh_key,((DSA *)(EVP_PKEY_get0(pubk)))->pub_key,dh) ;
     DH_free(dh);
     if (!ret)
         return 0;
-    init_gost_hash_ctx(&hash_ctx, &GostR3411_94_CryptoProParamSet);
+    init_gost_hash_ctx(&hash_ctx,
+        get_encryption_params(OBJ_nid2obj(ex_data == NULL || ex_data->hash_params_nid == NID_undef
+            ? NID_id_GostR3411_94_CryptoProParamSet
+            : ex_data->hash_params_nid))->sblock);
     start_hash(&hash_ctx);
-    hash_block(&hash_ctx, dh_key, 128);
-    finish_hash(&hash_ctx, shared_key);
+    hash_block(&hash_ctx,dh_key,128);
+    finish_hash(&hash_ctx,shared_key);
     done_gost_hash_ctx(&hash_ctx);
     return 1;
 }
@@ -85,7 +88,7 @@
     if (key == NULL)
         return 1;
 
-    return make_cp_exchange_key(gost_get0_priv_key(mykey), pubk, key);
+    return make_cp_exchange_key(mykey, pubk, key);
 }
 
 /*
@@ -106,6 +109,11 @@
     int key_is_ephemeral = 1;
     int tmp_outlen;
     EVP_PKEY *mykey = EVP_PKEY_CTX_get0_peerkey(ctx);
+    GOST3410_EX_DATA *ex_data = (GOST3410_EX_DATA *)GOST3410_get_ex_data(pubk);
+
+    if (ex_data != NULL && ex_data->cipher_params_nid != NID_undef) {
+      param = get_encryption_params(OBJ_nid2obj(ex_data->cipher_params_nid));
+    }
 
     /* Do not use vizir cipher parameters with cryptopro */
     if (!get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS)
@@ -134,7 +142,7 @@
         }
     }
     if (out)
-        make_cp_exchange_key(gost_get0_priv_key(mykey), pubk, shared_key);
+        make_cp_exchange_key(mykey, pubk, shared_key);
     if (data->shared_ukm) {
         memcpy(ukm, data->shared_ukm, 8);
     } else if (out) {
@@ -263,7 +271,7 @@
     memcpy(wrappedKey + 8, gkt->key_info->encrypted_key->data, 32);
     OPENSSL_assert(gkt->key_info->imit->length == 4);
     memcpy(wrappedKey + 40, gkt->key_info->imit->data, 4);
-    make_cp_exchange_key(gost_get0_priv_key(priv), peerkey, sharedKey);
+    make_cp_exchange_key(priv, peerkey, sharedKey);
     if (!keyUnwrapCryptoPro(&cctx, sharedKey, wrappedKey, key)) {
         GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,
                 GOST_R_ERROR_COMPUTING_SHARED_KEY);
diff -Naur --no-dereference openssl-1.0.2d/engines/ccgost/gost_ameth.c openssl-1.0.2d.new/engines/ccgost/gost_ameth.c
--- openssl-1.0.2d/engines/ccgost/gost_ameth.c	2015-07-09 11:53:21.000000000 +0000
+++ openssl-1.0.2d.new/engines/ccgost/gost_ameth.c	2015-08-07 06:09:44.000000000 +0000
@@ -24,7 +24,7 @@
 {
     R3410_params *gost_params;
     BIGNUM *q = BN_new();
-    for (gost_params = R3410_paramset; gost_params->q != NULL; gost_params++) {
+    for (gost_params = R3410_paramset; gost_params != NULL; gost_params = gost_params->next) {
         BN_dec2bn(&q, gost_params->q);
         if (!BN_cmp(q, p->q)) {
             BN_free(q);
@@ -40,6 +40,7 @@
     ASN1_STRING *params = ASN1_STRING_new();
     GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new();
     int pkey_param_nid = NID_undef;
+    GOST3410_EX_DATA *ex_data = NULL;
 
     if (!params || !gkp) {
         GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, ERR_R_MALLOC_FAILURE);
@@ -65,11 +66,16 @@
         }
         break;
     }
+
+    ex_data = GOST3410_get_ex_data(key);
+    if (ex_data != NULL) {
+      gkp->hash_params = OBJ_nid2obj(ex_data->hash_params_nid);
+      gkp->cipher_params = OBJ_nid2obj(ex_data->cipher_params_nid);
+    }
+    else
+      gkp->hash_params = OBJ_nid2obj(NID_id_GostR3411_94_CryptoProParamSet);
+
     gkp->key_params = OBJ_nid2obj(pkey_param_nid);
-    gkp->hash_params = OBJ_nid2obj(NID_id_GostR3411_94_CryptoProParamSet);
-    /*
-     * gkp->cipher_params = OBJ_nid2obj(cipher_param_nid);
-     */
     params->length = i2d_GOST_KEY_PARAMS(gkp, &params->data);
     if (params->length <= 0) {
         GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, ERR_R_MALLOC_FAILURE);
@@ -92,10 +98,13 @@
     ASN1_OBJECT *palg_obj = NULL;
     int ptype = V_ASN1_UNDEF;
     int pkey_nid = NID_undef, param_nid = NID_undef;
+    int hash_params_nid = NID_undef;
+    int cipher_params_nid = NID_undef;
     void *_pval;
     ASN1_STRING *pval = NULL;
     const unsigned char *p;
     GOST_KEY_PARAMS *gkp = NULL;
+    GOST3410_EX_DATA *ex_data = NULL;
 
     X509_ALGOR_get0(&palg_obj, &ptype, &_pval, palg);
     pval = _pval;
@@ -114,6 +123,8 @@
         return 0;
     }
     param_nid = OBJ_obj2nid(gkp->key_params);
+    hash_params_nid = OBJ_obj2nid(gkp->hash_params);
+    cipher_params_nid = OBJ_obj2nid(gkp->cipher_params);
     GOST_KEY_PARAMS_free(gkp);
     if(!EVP_PKEY_set_type(pkey, pkey_nid)) {
         GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, ERR_R_INTERNAL_ERROR);
@@ -145,6 +156,12 @@
         }
     }
 
+    ex_data = GOST3410_get_ex_data(pkey);
+    if (!ex_data )
+        return 0;
+    ex_data->hash_params_nid = hash_params_nid;
+    ex_data->cipher_params_nid = cipher_params_nid;
+
     return 1;
 }
 
@@ -538,6 +555,10 @@
 
         if (dto->priv_key)
         gost94_compute_public(dto);
+
+    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, dto, &dto->ex_data);
+    CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_DSA, &dto->ex_data, (CRYPTO_EX_DATA *)&dfrom->ex_data);
+
     return 1;
 }
 
@@ -571,6 +592,11 @@
     if (EC_KEY_get0_private_key(eto)) {
         gost2001_compute_public(eto);
     }
+
+    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_GOST3410, ecgost_check(eto), &ecgost_check(eto)->ex_data);
+    CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_GOST3410, &ecgost_check(eto)->ex_data,
+                       &ecgost_check((EC_KEY *)efrom)->ex_data);
+
     return 1;
 }
 
diff -Naur --no-dereference openssl-1.0.2d/engines/ccgost/gost_crypt.c openssl-1.0.2d.new/engines/ccgost/gost_crypt.c
--- openssl-1.0.2d/engines/ccgost/gost_crypt.c	2015-07-09 11:57:15.000000000 +0000
+++ openssl-1.0.2d.new/engines/ccgost/gost_crypt.c	2015-08-07 06:09:44.000000000 +0000
@@ -109,27 +109,23 @@
  */
 
 struct gost_cipher_info gost_cipher_list[] = {
-    /*- NID *//*
-     * Subst block
-     *//*
-     * Key meshing
-     */
-    /*
-     * {NID_id_GostR3411_94_CryptoProParamSet,&GostR3411_94_CryptoProParamSet,0},
-     */
-    {NID_id_Gost28147_89_cc, &GostR3411_94_CryptoProParamSet, 0},
-    {NID_id_Gost28147_89_CryptoPro_A_ParamSet, &Gost28147_CryptoProParamSetA,
-     1},
-    {NID_id_Gost28147_89_CryptoPro_B_ParamSet, &Gost28147_CryptoProParamSetB,
-     1},
-    {NID_id_Gost28147_89_CryptoPro_C_ParamSet, &Gost28147_CryptoProParamSetC,
-     1},
-    {NID_id_Gost28147_89_CryptoPro_D_ParamSet, &Gost28147_CryptoProParamSetD,
-     1},
-    {NID_id_Gost28147_89_TestParamSet, &Gost28147_TestParamSet, 1},
-    {NID_undef, NULL, 0}
+    /* NID */                                 /* Subst block */     /* Key meshing*/ /* Next entry */
+    {NID_id_Gost28147_89_cc,                  &GostR3411_94_CryptoProParamSet,0,&gost_cipher_list[1]},
+    {NID_id_Gost28147_89_CryptoPro_A_ParamSet,&Gost28147_CryptoProParamSetA,  1,&gost_cipher_list[2]},
+    {NID_id_Gost28147_89_CryptoPro_B_ParamSet,&Gost28147_CryptoProParamSetB,  1,&gost_cipher_list[3]},
+    {NID_id_Gost28147_89_CryptoPro_C_ParamSet,&Gost28147_CryptoProParamSetC,  1,&gost_cipher_list[4]},
+    {NID_id_Gost28147_89_CryptoPro_D_ParamSet,&Gost28147_CryptoProParamSetD,  1,&gost_cipher_list[5]},
+    {NID_id_Gost28147_89_TestParamSet,        &Gost28147_TestParamSet,        1,&gost_cipher_list[6]},
+    {NID_id_GostR3411_94_CryptoProParamSet,   &GostR3411_94_CryptoProParamSet,0,NULL},
 };
 
+void gost_cipher_list_append(struct gost_cipher_info *param)
+{
+  struct gost_cipher_info *p;
+  for (p=gost_cipher_list; p->next; p=p->next);
+  p->next = param;
+}
+
 /*
  * get encryption parameters from crypto network settings FIXME For now we
  * use environment var CRYPT_PARAMS as place to store these settings.
@@ -154,9 +150,9 @@
     } else {
         nid = OBJ_obj2nid(obj);
     }
-    for (param = gost_cipher_list; param->sblock != NULL && param->nid != nid;
-         param++) ;
-    if (!param->sblock) {
+    for (param=gost_cipher_list;param!=NULL && param->nid!=nid;
+         param=param->next);
+    if (param == NULL) {
         GOSTerr(GOST_F_GET_ENCRYPTION_PARAMS, GOST_R_INVALID_CIPHER_PARAMS);
         return NULL;
     }
diff -Naur --no-dereference openssl-1.0.2d/engines/ccgost/gost_eng.c openssl-1.0.2d.new/engines/ccgost/gost_eng.c
--- openssl-1.0.2d/engines/ccgost/gost_eng.c	2015-06-11 14:44:27.000000000 +0000
+++ openssl-1.0.2d.new/engines/ccgost/gost_eng.c	2015-08-07 06:09:44.000000000 +0000
@@ -50,7 +50,7 @@
 
 static int gost_engine_init(ENGINE *e)
 {
-    return 1;
+    return gost_make_indices();
 }
 
 static int gost_engine_finish(ENGINE *e)
diff -Naur --no-dereference openssl-1.0.2d/engines/ccgost/gost_lcl.h openssl-1.0.2d.new/engines/ccgost/gost_lcl.h
--- openssl-1.0.2d/engines/ccgost/gost_lcl.h	2015-06-11 14:44:27.000000000 +0000
+++ openssl-1.0.2d.new/engines/ccgost/gost_lcl.h	2015-08-07 06:09:44.000000000 +0000
@@ -16,8 +16,12 @@
 # include <openssl/x509.h>
 # include <openssl/engine.h>
 # include <openssl/ec.h>
+#ifdef  __cplusplus
+extern "C" {
+#endif
 # include "gost89.h"
 # include "gosthash.h"
+# include "gost_params.h"
 /* Control commands */
 # define GOST_PARAM_CRYPT_PARAMS 0
 # define GOST_PARAM_MAX 0
@@ -146,6 +150,7 @@
     int nid;
     gost_subst_block *sblock;
     int key_meshing;
+    struct gost_cipher_info *next;
 };
 /* Context for MAC */
 struct ossl_gost_imit_ctx {
@@ -159,6 +164,8 @@
 };
 /* Table which maps parameter NID to S-blocks */
 extern struct gost_cipher_info gost_cipher_list[];
+/* Append custom mapping parameter NID to S-blocks */
+void gost_cipher_list_append(struct gost_cipher_info *param);
 /* Find encryption params from ASN1_OBJECT */
 const struct gost_cipher_info *get_encryption_params(ASN1_OBJECT *obj);
 /* Implementation of GOST 28147-89 cipher in CFB and CNT modes */
@@ -204,6 +211,9 @@
                        DSA_SIG *sig, EC_KEY *ec);
 int gost2001_compute_public(EC_KEY *ec);
 int gost94_compute_public(DSA *dsa);
+
+void gost94_paramset_append(struct R3410 *param);
+void gost2001_paramset_append(struct R3410_2001 *param);
 /*============== miscellaneous functions============================= */
 /* from gost_sign.c */
 /* Convert GOST R 34.11 hash sum to bignum according to standard */
@@ -226,4 +236,29 @@
 /* Find NID by GOST 94 parameters */
 int gost94_nid_by_params(DSA *p);
 
+extern int gost3410_94_ex_data_idx;
+extern int gost3410_2001_ex_data_idx;
+
+int gost_make_indices();
+
+typedef struct ecgost_data_st {
+	CRYPTO_EX_DATA ex_data;
+} ECGOST_DATA;
+
+/* Extra params using in key exchange */
+typedef struct gost3410_ex_data_st {
+	int hash_params_nid;
+	int cipher_params_nid;
+} GOST3410_EX_DATA;
+
+int GOST3410_set_ex_data(EVP_PKEY *key,GOST3410_EX_DATA *arg);
+GOST3410_EX_DATA *GOST3410_get_ex_data(const EVP_PKEY *key);
+
+/* Check for ex data and create if not exists */
+ECGOST_DATA *ecgost_check(EC_KEY *);
+
+#ifdef  __cplusplus
+}
+#endif
+
 #endif
diff -Naur --no-dereference openssl-1.0.2d/engines/ccgost/gost_lib.c openssl-1.0.2d.new/engines/ccgost/gost_lib.c
--- openssl-1.0.2d/engines/ccgost/gost_lib.c	1970-01-01 00:00:00.000000000 +0000
+++ openssl-1.0.2d.new/engines/ccgost/gost_lib.c	2015-08-07 06:09:44.000000000 +0000
@@ -0,0 +1,256 @@
+/* engines/ccgost/gost_lib.c */
+/* ====================================================================
+ * Copyright (c) 1998-2014 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-c...@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (e...@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (t...@cryptsoft.com).
+ *
+ */
+
+#include "gost_lcl.h"
+#include "e_gost_err.h"
+
+int gost3410_94_ex_data_idx = -1;
+int gost3410_2001_ex_data_idx = -1;
+
+static void *ecgost_data_new(void);
+static void *ecgost_data_dup(void *);
+static void  ecgost_data_free(void *);
+
+static int gost_ex_data_new(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+	int idx, long argl, void *argp);
+static void gost_ex_data_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+	int idx, long argl, void *argp);
+static int gost_ex_data_dup(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, void *from_d, 
+	int idx, long argl, void *argp);
+
+static CRYPTO_EX_DATA *gost_ex_data_get(const EVP_PKEY *key, int *idx);
+static int GOST3410_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+
+
+static void *ecgost_data_new(void)
+	{
+	ECGOST_DATA *ret;
+
+	ret=(ECGOST_DATA *)OPENSSL_malloc(sizeof(ECGOST_DATA));
+	if (ret == NULL)
+		{
+		GOSTerr(GOST_F_ECGOST_DATA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+
+	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_GOST3410, ret, &ret->ex_data);
+
+	return(ret);
+	}
+
+static void *ecgost_data_dup(void *data)
+	{
+	ECGOST_DATA *ec_data = (ECGOST_DATA *)data;
+	ECGOST_DATA *ret = NULL;
+
+	if (ec_data == NULL)
+		return NULL;
+
+	ret = ecgost_data_new();
+	if (ret != NULL)
+		CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_GOST3410, &ret->ex_data, &ec_data->ex_data);
+
+	return ret;
+	}
+
+static void ecgost_data_free(void *data)
+	{
+	ECGOST_DATA *r = (ECGOST_DATA *)data;
+
+	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_GOST3410, r, &r->ex_data);
+
+	OPENSSL_cleanse((void *)r, sizeof(ECGOST_DATA));
+
+	OPENSSL_free(r);
+	}
+
+static int gost_ex_data_new(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+	int idx, long argl, void *argp)
+	{
+	GOST3410_EX_DATA *ex_data;
+
+	if (ptr == NULL )
+		{
+		ptr = (GOST3410_EX_DATA *)OPENSSL_malloc(sizeof(GOST3410_EX_DATA));
+
+		if (ptr == NULL)
+			{
+			GOSTerr(GOST_F_GOST3410_EX_DATA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+
+		CRYPTO_set_ex_data(ad, idx, ptr);
+		}
+
+	ex_data = ptr;
+
+	ex_data->hash_params_nid = NID_id_GostR3411_94_CryptoProParamSet;
+	ex_data->cipher_params_nid = NID_id_Gost28147_89_CryptoPro_A_ParamSet;
+
+	return 1;
+	}
+
+static void gost_ex_data_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+	int idx, long argl, void *argp)
+	{
+	if (ptr != NULL)
+		{
+			OPENSSL_cleanse(ptr, sizeof(GOST3410_EX_DATA));
+			OPENSSL_free(ptr);
+		}
+	}
+
+static int gost_ex_data_dup(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, void *from_d, 
+	int idx, long argl, void *argp)
+	{
+	GOST3410_EX_DATA **ex_data = (GOST3410_EX_DATA **)from_d;
+	GOST3410_EX_DATA *ret = (GOST3410_EX_DATA *)OPENSSL_malloc(sizeof(GOST3410_EX_DATA));
+
+	if (ret == NULL)
+		return 0;
+
+	ret->hash_params_nid = (*ex_data)->hash_params_nid;
+	ret->cipher_params_nid = (*ex_data)->cipher_params_nid;
+	*ex_data = ret;
+
+	return 1;
+	}
+
+static CRYPTO_EX_DATA *gost_ex_data_get(const EVP_PKEY *key, int *idx)
+	{
+	switch (EVP_PKEY_base_id(key)) 
+		{
+		case NID_id_GostR3410_2001:
+			*idx = gost3410_2001_ex_data_idx;
+			return &ecgost_check(EVP_PKEY_get0((EVP_PKEY *)key))->ex_data;
+		case NID_id_GostR3410_94:
+			*idx = gost3410_94_ex_data_idx;
+			return &((DSA *)EVP_PKEY_get0((EVP_PKEY *)key))->ex_data;
+		}
+	return NULL;
+	}
+
+int gost_make_indices()
+	{
+	if (gost3410_94_ex_data_idx == -1)
+		gost3410_94_ex_data_idx = DSA_get_ex_new_index(0, NULL,
+			&gost_ex_data_new, &gost_ex_data_dup, &gost_ex_data_free);
+
+	if (gost3410_2001_ex_data_idx == -1)
+		gost3410_2001_ex_data_idx = GOST3410_get_ex_new_index(0, NULL,
+			&gost_ex_data_new, &gost_ex_data_dup, &gost_ex_data_free);
+
+	if (gost3410_94_ex_data_idx < 0 || gost3410_2001_ex_data_idx < 0)
+		return 0;
+
+	return 1;
+	}
+
+int GOST3410_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+	{
+	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_GOST3410, argl, argp,
+		new_func, dup_func, free_func);
+	}
+
+int GOST3410_set_ex_data(EVP_PKEY *key,GOST3410_EX_DATA *arg)
+	{
+	int idx = 0;
+	CRYPTO_EX_DATA *ex_data = gost_ex_data_get(key, &idx);
+
+	if (ex_data == NULL)
+		return 0;
+
+	return(CRYPTO_set_ex_data(ex_data,idx,arg));
+	}
+
+GOST3410_EX_DATA *GOST3410_get_ex_data(const EVP_PKEY *key)
+	{
+	int idx = 0;
+	CRYPTO_EX_DATA *ex_data = gost_ex_data_get(key, &idx);
+
+	if (ex_data == NULL)
+		return NULL;
+
+	return(CRYPTO_get_ex_data(ex_data,idx));
+	}
+
+ECGOST_DATA *ecgost_check(EC_KEY *key)
+	{
+	ECGOST_DATA *ecgost_data;
+ 
+	void *data = EC_KEY_get_key_method_data(key, ecgost_data_dup,
+					ecgost_data_free, ecgost_data_free);
+	if (data == NULL)
+	{
+		ecgost_data = (ECGOST_DATA *)ecgost_data_new();
+		if (ecgost_data == NULL)
+			return NULL;
+		data = EC_KEY_insert_key_method_data(key, (void *)ecgost_data,
+			   ecgost_data_dup, ecgost_data_free, ecgost_data_free);
+		if (data != NULL)
+			{
+			/* Another thread raced us to install the key_method
+			 * data and won. */
+			ecgost_data_free(ecgost_data);
+			ecgost_data = (ECGOST_DATA *)data;
+			}
+	}
+	else
+		ecgost_data = (ECGOST_DATA *)data;
+
+	return ecgost_data;
+	}
diff -Naur --no-dereference openssl-1.0.2d/engines/ccgost/gost_params.c openssl-1.0.2d.new/engines/ccgost/gost_params.c
--- openssl-1.0.2d/engines/ccgost/gost_params.c	2015-06-11 14:44:27.000000000 +0000
+++ openssl-1.0.2d.new/engines/ccgost/gost_params.c	2015-08-07 06:09:44.000000000 +0000
@@ -27,7 +27,8 @@
      "2227508135323070045173416336850045410625869714168836867788425378203"
      "83",
      "683631961449557007844441656118272528951"
-     "02170888761442055095051287550314083023"}
+     "02170888761442055095051287550314083023",
+     &R3410_paramset[1]}
     ,
     {NID_id_GostR3410_94_CryptoPro_B_ParamSet,
      "429418261486158041438734477379555023926"
@@ -42,7 +43,8 @@
      "7694904686120113087816240740184800477047157336662926249423571248823"
      "9685422217536601433914856808405203368594584948031873412885804895251"
      "63",
-     "79885141663410976897627118935756323747307951916507639758300472692338873533959"}
+     "79885141663410976897627118935756323747307951916507639758300472692338873533959",
+     &R3410_paramset[2]}
     ,
     {NID_id_GostR3410_94_CryptoPro_C_ParamSet,
      "816552717970881016017893191415300348226"
@@ -58,7 +60,8 @@
      "3542287621283671843703709141350171945045805050291770503634517804938"
      "01",
      "113468861199819350564868233378875198043"
-     "267947776488510997961231672532899549103"}
+     "267947776488510997961231672532899549103",
+     &R3410_paramset[3]}
     ,
     {NID_id_GostR3410_94_CryptoPro_D_ParamSet,
      "756976611021707301782128757801610628085"
@@ -74,7 +77,8 @@
      "8574828787891286471201460474326612697849693665518073864436497893214"
      "9",
      "108988435796353506912374591498972192620"
-     "190487557619582334771735390599299211593"}
+     "190487557619582334771735390599299211593",
+     &R3410_paramset[4]}
     ,
 
     {NID_id_GostR3410_94_CryptoPro_XchA_ParamSet,
@@ -89,7 +93,8 @@
      "72895683154177544176313938445719175509684710784659566254794231229333"
      "8483924514339614727760681880609734239",
      "91771529896554605945588149018382750217296858393520724172743325725474"
-     "374979801"}
+     "374979801",
+     &R3410_paramset[5]}
     ,
     {NID_id_GostR3410_94_CryptoPro_XchB_ParamSet,
      "8890864727828423151699995801875757891031463338652579140051973659"
@@ -103,7 +108,8 @@
      "7200196629860561193666752429682367397084815179752036423595736533"
      "68957392061769855284593965042530895046088067160269433",
      "9109671391802626916582318050603555673628769498182593088388796888"
-     "5281641595199"}
+     "5281641595199",
+     &R3410_paramset[6]}
     ,
     {NID_id_GostR3410_94_CryptoPro_XchC_ParamSet,
      "4430618464297584182473135030809859326863990650118941756995270074"
@@ -117,10 +123,9 @@
      "0448079715771649447778447000597419032457722226253269698374446528"
      "35352729304393746106576383349151001715930924115499549",
      "6787876137336591234380295020065682527118129468050147943114675429"
-     "4748422492761"}
+     "4748422492761",
+     NULL}
     ,
-
-    {NID_undef, NULL, NULL, NULL}
 };
 
 R3410_2001_params R3410_2001_paramset[] = {
@@ -137,7 +142,8 @@
      /* X */
      "2",
      /* Y */
-     "a20e034bf8813ef5c18d01105e726a17eb248b264ae9706f440bedc8ccb6b22c"}
+     "a20e034bf8813ef5c18d01105e726a17eb248b264ae9706f440bedc8ccb6b22c",
+     &R3410_2001_paramset[1]}
     ,
     /* 1.2.643.2.2.35.0 */
     {NID_id_GostR3410_2001_TestParamSet,
@@ -146,7 +152,8 @@
      "8000000000000000000000000000000000000000000000000000000000000431",
      "8000000000000000000000000000000150FE8A1892976154C59CFC193ACCF5B3",
      "2",
-     "08E2A8A0E65147D4BD6316030E16D19C85C97F0A9CA267122B96ABBCEA7E8FC8"}
+     "08E2A8A0E65147D4BD6316030E16D19C85C97F0A9CA267122B96ABBCEA7E8FC8",
+     &R3410_2001_paramset[2]}
     ,
     /*
      * 1.2.643.2.2.35.1
@@ -157,7 +164,8 @@
      "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97",
      "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893",
      "1",
-     "8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14"}
+     "8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14",
+     &R3410_2001_paramset[3]}
     ,
     /*
      * 1.2.643.2.2.35.2
@@ -168,7 +176,8 @@
      "8000000000000000000000000000000000000000000000000000000000000C99",
      "800000000000000000000000000000015F700CFFF1A624E5E497161BCC8A198F",
      "1",
-     "3FA8124359F96680B83D1C3EB2C070E5C545C9858D03ECFB744BF8D717717EFC"}
+     "3FA8124359F96680B83D1C3EB2C070E5C545C9858D03ECFB744BF8D717717EFC",
+     &R3410_2001_paramset[4]}
     ,
     /*
      * 1.2.643.2.2.35.3
@@ -179,7 +188,8 @@
      "9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D759B",
      "9B9F605F5A858107AB1EC85E6B41C8AA582CA3511EDDFB74F02F3A6598980BB9",
      "0",
-     "41ECE55743711A8C3CBF3783CD08C0EE4D4DC440D4641A8F366E550DFDB3BB67"}
+     "41ECE55743711A8C3CBF3783CD08C0EE4D4DC440D4641A8F366E550DFDB3BB67",
+     &R3410_2001_paramset[5]}
     ,
     /*
      * 1.2.643.2.2.36.0
@@ -190,7 +200,8 @@
      "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97",
      "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893",
      "1",
-     "8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14"}
+     "8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14",
+     &R3410_2001_paramset[6]}
     ,
     /*
      * 1.2.643.2.2.36.1
@@ -201,7 +212,8 @@
      "9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D759B",
      "9B9F605F5A858107AB1EC85E6B41C8AA582CA3511EDDFB74F02F3A6598980BB9",
      "0",
-     "41ECE55743711A8C3CBF3783CD08C0EE4D4DC440D4641A8F366E550DFDB3BB67"}
+     "41ECE55743711A8C3CBF3783CD08C0EE4D4DC440D4641A8F366E550DFDB3BB67",
+     NULL
+    }
     ,
-    {0, NULL, NULL, NULL, NULL, NULL, NULL}
 };
diff -Naur --no-dereference openssl-1.0.2d/engines/ccgost/gost_params.h openssl-1.0.2d.new/engines/ccgost/gost_params.h
--- openssl-1.0.2d/engines/ccgost/gost_params.h	2015-06-11 14:44:27.000000000 +0000
+++ openssl-1.0.2d.new/engines/ccgost/gost_params.h	2015-08-07 06:09:44.000000000 +0000
@@ -10,11 +10,15 @@
  **********************************************************************/
 #ifndef GOST_PARAMSET_H
 # define GOST_PARAMSET_H
+#ifdef __cplusplus
+extern "C" {
+#endif
 typedef struct R3410 {
     int nid;
     char *a;
     char *p;
     char *q;
+    struct R3410 *next;
 } R3410_params;
 
 extern R3410_params R3410_paramset[];
@@ -27,8 +31,12 @@
     char *q;
     char *x;
     char *y;
+    struct R3410_2001 *next;
 } R3410_2001_params;
 
 extern R3410_2001_params R3410_2001_paramset[];
 
+#ifdef __cplusplus
+}
+#endif
 #endif
diff -Naur --no-dereference openssl-1.0.2d/engines/ccgost/gost_pmeth.c openssl-1.0.2d.new/engines/ccgost/gost_pmeth.c
--- openssl-1.0.2d/engines/ccgost/gost_pmeth.c	2015-07-09 11:57:15.000000000 +0000
+++ openssl-1.0.2d.new/engines/ccgost/gost_pmeth.c	2015-08-07 06:09:44.000000000 +0000
@@ -169,11 +169,11 @@
             if (param_nid == NID_undef) {
                 return 0;
             }
-            for (; p->nid != NID_undef; p++) {
+            for (;p != NULL; p = p->next) {
                 if (p->nid == param_nid)
                     break;
             }
-            if (p->nid == NID_undef) {
+            if (p == NULL) {
                 GOSTerr(GOST_F_PKEY_GOST_CTRL94_STR, GOST_R_INVALID_PARAMSET);
                 return 0;
             }
@@ -230,11 +230,11 @@
             if (param_nid == NID_undef) {
                 return 0;
             }
-            for (; p->nid != NID_undef; p++) {
+            for (;p != NULL; p = p->next) {
                 if (p->nid == param_nid)
                     break;
             }
-            if (p->nid == NID_undef) {
+            if (p == NULL) {
                 GOSTerr(GOST_F_PKEY_GOST_CTRL01_STR, GOST_R_INVALID_PARAMSET);
                 return 0;
             }
diff -Naur --no-dereference openssl-1.0.2d/engines/ccgost/gost_sign.c openssl-1.0.2d.new/engines/ccgost/gost_sign.c
--- openssl-1.0.2d/engines/ccgost/gost_sign.c	2015-07-09 11:53:21.000000000 +0000
+++ openssl-1.0.2d.new/engines/ccgost/gost_sign.c	2015-08-07 06:09:44.000000000 +0000
@@ -259,9 +259,9 @@
 int fill_GOST94_params(DSA *dsa, int nid)
 {
     R3410_params *params = R3410_paramset;
-    while (params->nid != NID_undef && params->nid != nid)
-        params++;
-    if (params->nid == NID_undef) {
+    while (params!=NULL && params->nid !=nid)
+      params = params->next;
+    if (params == NULL) {
         GOSTerr(GOST_F_FILL_GOST94_PARAMS, GOST_R_UNSUPPORTED_PARAMETER_SET);
         return 0;
     }
@@ -371,3 +371,10 @@
     BN_bn2bin(bn, buf + len - bytes);
     return 1;
 }
+
+void gost94_paramset_append(struct R3410 *param)
+{
+    struct R3410 *p;
+    for (p = R3410_paramset; p->next; p = p->next);
+    p->next = param;
+}
diff -Naur --no-dereference openssl-1.0.2d/engines/makeengines.com openssl-1.0.2d.new/engines/makeengines.com
--- openssl-1.0.2d/engines/makeengines.com	2015-07-09 11:57:15.000000000 +0000
+++ openssl-1.0.2d.new/engines/makeengines.com	2015-08-07 06:09:44.000000000 +0000
@@ -168,7 +168,7 @@
 $ ENGINE_ccgost_SUBDIR = "ccgost"
 $ ENGINE_ccgost = "e_gost_err,gost2001_keyx,gost2001,gost89,gost94_keyx,"+ -
 		  "gost_ameth,gost_asn1,gost_crypt,gost_ctl,gost_eng,"+ -
-		  "gosthash,gost_keywrap,gost_md,gost_params,gost_pmeth,"+ -
+		  "gosthash,gost_keywrap,gost_lib,gost_md,gost_params,gost_pmeth,"+ -
 		  "gost_sign"
 $!
 $! Define which programs need to be linked with a TCP/IP library
_______________________________________________
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev

Reply via email to