opensslgost_link.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2010-2014  Internet Systems Consortium, Inc. ("ISC")
00003  *
00004  * Permission to use, copy, modify, and/or distribute this software for any
00005  * purpose with or without fee is hereby granted, provided that the above
00006  * copyright notice and this permission notice appear in all copies.
00007  *
00008  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00009  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00010  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00011  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00012  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00013  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00014  * PERFORMANCE OF THIS SOFTWARE.
00015  */
00016 
00017 /* $Id: opensslgost_link.c,v 1.5 2011/01/19 23:47:12 tbox Exp $ */
00018 
00019 #include <config.h>
00020 
00021 #if defined(OPENSSL) && defined(HAVE_OPENSSL_GOST)
00022 
00023 #include <isc/entropy.h>
00024 #include <isc/mem.h>
00025 #include <isc/string.h>
00026 #include <isc/util.h>
00027 
00028 #include <dst/result.h>
00029 
00030 #include "dst_internal.h"
00031 #include "dst_openssl.h"
00032 #include "dst_parse.h"
00033 #include "dst_gost.h"
00034 
00035 #include <openssl/err.h>
00036 #include <openssl/objects.h>
00037 #include <openssl/rsa.h>
00038 #include <openssl/engine.h>
00039 
00040 static ENGINE *e = NULL;
00041 static const EVP_MD *opensslgost_digest;
00042 extern const EVP_MD *EVP_gost(void);
00043 
00044 const EVP_MD *EVP_gost(void) {
00045         return (opensslgost_digest);
00046 }
00047 
00048 /* ISC methods */
00049 
00050 isc_result_t
00051 isc_gost_init(isc_gost_t *ctx) {
00052         const EVP_MD *md;
00053         int ret;
00054 
00055         INSIST(ctx != NULL);
00056 
00057         md = EVP_gost();
00058         if (md == NULL)
00059                 return (DST_R_CRYPTOFAILURE);
00060         EVP_MD_CTX_init(ctx);
00061         ret = EVP_DigestInit(ctx, md);
00062         if (ret != 1)
00063                 return (DST_R_CRYPTOFAILURE);
00064         return (ISC_R_SUCCESS);
00065 }
00066 
00067 void
00068 isc_gost_invalidate(isc_gost_t *ctx) {
00069         EVP_MD_CTX_cleanup(ctx);
00070 }
00071 
00072 isc_result_t
00073 isc_gost_update(isc_gost_t *ctx, const unsigned char *data,
00074                 unsigned int len)
00075 {
00076         int ret;
00077 
00078         INSIST(ctx != NULL);
00079         INSIST(data != NULL);
00080 
00081         ret = EVP_DigestUpdate(ctx, (const void *) data, (size_t) len);
00082         if (ret != 1)
00083                 return (DST_R_CRYPTOFAILURE);
00084         return (ISC_R_SUCCESS);
00085 }
00086 
00087 isc_result_t
00088 isc_gost_final(isc_gost_t *ctx, unsigned char *digest) {
00089         int ret;
00090 
00091         INSIST(ctx != NULL);
00092         INSIST(digest != NULL);
00093 
00094         ret = EVP_DigestFinal(ctx, digest, NULL);
00095         if (ret != 1)
00096                 return (DST_R_CRYPTOFAILURE);
00097         return (ISC_R_SUCCESS);
00098 }
00099 
00100 /* DST methods */
00101 
00102 #define DST_RET(a) {ret = a; goto err;}
00103 
00104 static isc_result_t opensslgost_todns(const dst_key_t *key,
00105                                       isc_buffer_t *data);
00106 
00107 static isc_result_t
00108 opensslgost_createctx(dst_key_t *key, dst_context_t *dctx) {
00109         EVP_MD_CTX *evp_md_ctx;
00110         const EVP_MD *md = EVP_gost();
00111 
00112         UNUSED(key);
00113 
00114         if (md == NULL)
00115                 return (DST_R_OPENSSLFAILURE);
00116 
00117         evp_md_ctx = EVP_MD_CTX_create();
00118         if (evp_md_ctx == NULL)
00119                 return (ISC_R_NOMEMORY);
00120 
00121         if (!EVP_DigestInit_ex(evp_md_ctx, md, NULL)) {
00122                 EVP_MD_CTX_destroy(evp_md_ctx);
00123                 return (ISC_R_FAILURE);
00124         }
00125         dctx->ctxdata.evp_md_ctx = evp_md_ctx;
00126 
00127         return (ISC_R_SUCCESS);
00128 }
00129 
00130 static void
00131 opensslgost_destroyctx(dst_context_t *dctx) {
00132         EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
00133 
00134         if (evp_md_ctx != NULL) {
00135                 EVP_MD_CTX_destroy(evp_md_ctx);
00136                 dctx->ctxdata.evp_md_ctx = NULL;
00137         }
00138 }
00139 
00140 static isc_result_t
00141 opensslgost_adddata(dst_context_t *dctx, const isc_region_t *data) {
00142         EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
00143 
00144         if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length))
00145                 return (ISC_R_FAILURE);
00146 
00147         return (ISC_R_SUCCESS);
00148 }
00149 
00150 static isc_result_t
00151 opensslgost_sign(dst_context_t *dctx, isc_buffer_t *sig) {
00152         dst_key_t *key = dctx->key;
00153         isc_region_t r;
00154         unsigned int siglen = 0;
00155         EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
00156         EVP_PKEY *pkey = key->keydata.pkey;
00157 
00158         isc_buffer_availableregion(sig, &r);
00159 
00160         if (r.length < (unsigned int) EVP_PKEY_size(pkey))
00161                 return (ISC_R_NOSPACE);
00162 
00163         if (!EVP_SignFinal(evp_md_ctx, r.base, &siglen, pkey))
00164                 return (ISC_R_FAILURE);
00165 
00166         isc_buffer_add(sig, siglen);
00167 
00168         return (ISC_R_SUCCESS);
00169 }
00170 
00171 static isc_result_t
00172 opensslgost_verify(dst_context_t *dctx, const isc_region_t *sig) {
00173         dst_key_t *key = dctx->key;
00174         int status = 0;
00175         EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
00176         EVP_PKEY *pkey = key->keydata.pkey;
00177 
00178         status = EVP_VerifyFinal(evp_md_ctx, sig->base, sig->length, pkey);
00179         switch (status) {
00180         case 1:
00181                 return (ISC_R_SUCCESS);
00182         case 0:
00183                 return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
00184         default:
00185                 return (dst__openssl_toresult3(dctx->category,
00186                                                "EVP_VerifyFinal",
00187                                                DST_R_VERIFYFAILURE));
00188         }
00189 }
00190 
00191 static isc_boolean_t
00192 opensslgost_compare(const dst_key_t *key1, const dst_key_t *key2) {
00193         EVP_PKEY *pkey1, *pkey2;
00194 
00195         pkey1 = key1->keydata.pkey;
00196         pkey2 = key2->keydata.pkey;
00197 
00198         if (pkey1 == NULL && pkey2 == NULL)
00199                 return (ISC_TRUE);
00200         else if (pkey1 == NULL || pkey2 == NULL)
00201                 return (ISC_FALSE);
00202 
00203         if (EVP_PKEY_cmp(pkey1, pkey2) != 1)
00204                 return (ISC_FALSE);
00205         return (ISC_TRUE);
00206 }
00207 
00208 static int
00209 progress_cb(EVP_PKEY_CTX *ctx)
00210 {
00211         union {
00212                 void *dptr;
00213                 void (*fptr)(int);
00214         } u;
00215         int p;
00216 
00217         u.dptr = EVP_PKEY_CTX_get_app_data(ctx);
00218         p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
00219         if (u.fptr != NULL)
00220                 u.fptr(p);
00221         return (1);
00222 }
00223 
00224 static isc_result_t
00225 opensslgost_generate(dst_key_t *key, int unused, void (*callback)(int)) {
00226         EVP_PKEY_CTX *ctx;
00227         union {
00228                 void *dptr;
00229                 void (*fptr)(int);
00230         } u;
00231         EVP_PKEY *pkey = NULL;
00232         isc_result_t ret;
00233 
00234         UNUSED(unused);
00235         ctx = EVP_PKEY_CTX_new_id(NID_id_GostR3410_2001, NULL);
00236         if (ctx == NULL)
00237                 DST_RET(dst__openssl_toresult2("EVP_PKEY_CTX_new_id",
00238                                                DST_R_OPENSSLFAILURE));
00239         if (callback != NULL) {
00240                 u.fptr = callback;
00241                 EVP_PKEY_CTX_set_app_data(ctx, u.dptr);
00242                 EVP_PKEY_CTX_set_cb(ctx, &progress_cb);
00243         }
00244         if (EVP_PKEY_keygen_init(ctx) <= 0)
00245                 DST_RET(dst__openssl_toresult2("EVP_PKEY_keygen_init",
00246                                                DST_R_OPENSSLFAILURE));
00247         if (EVP_PKEY_CTX_ctrl_str(ctx, "paramset", "A") <= 0)
00248                 DST_RET(dst__openssl_toresult2("EVP_PKEY_CTX_ctrl_str",
00249                                                DST_R_OPENSSLFAILURE));
00250         if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
00251                 DST_RET(dst__openssl_toresult2("EVP_PKEY_keygen",
00252                                                DST_R_OPENSSLFAILURE));
00253         key->keydata.pkey = pkey;
00254         key->key_size = EVP_PKEY_bits(pkey);
00255         EVP_PKEY_CTX_free(ctx);
00256         return (ISC_R_SUCCESS);
00257 
00258 err:
00259         if (pkey != NULL)
00260                 EVP_PKEY_free(pkey);
00261         if (ctx != NULL)
00262                 EVP_PKEY_CTX_free(ctx);
00263         return (ret);
00264 }
00265 
00266 static isc_boolean_t
00267 opensslgost_isprivate(const dst_key_t *key) {
00268         EVP_PKEY *pkey = key->keydata.pkey;
00269         EC_KEY *ec;
00270 
00271         INSIST(pkey != NULL);
00272 
00273         ec = EVP_PKEY_get0(pkey);
00274         return (ISC_TF(ec != NULL && EC_KEY_get0_private_key(ec) != NULL));
00275 }
00276 
00277 static void
00278 opensslgost_destroy(dst_key_t *key) {
00279         EVP_PKEY *pkey = key->keydata.pkey;
00280 
00281         EVP_PKEY_free(pkey);
00282         key->keydata.pkey = NULL;
00283 }
00284 
00285 unsigned char gost_prefix[37] = {
00286         0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85,
00287         0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07,
00288         0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01, 0x06,
00289         0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01,
00290         0x03, 0x43, 0x00, 0x04, 0x40
00291 };
00292 
00293 static isc_result_t
00294 opensslgost_todns(const dst_key_t *key, isc_buffer_t *data) {
00295         EVP_PKEY *pkey;
00296         isc_region_t r;
00297         unsigned char der[37 + 64], *p;
00298         int len;
00299 
00300         REQUIRE(key->keydata.pkey != NULL);
00301 
00302         pkey = key->keydata.pkey;
00303 
00304         isc_buffer_availableregion(data, &r);
00305         if (r.length < 64)
00306                 return (ISC_R_NOSPACE);
00307 
00308         p = der;
00309         len = i2d_PUBKEY(pkey, &p);
00310         INSIST(len == sizeof(der));
00311         INSIST(memcmp(gost_prefix, der, 37) == 0);
00312         memmove(r.base, der + 37, 64);
00313         isc_buffer_add(data, 64);
00314 
00315         return (ISC_R_SUCCESS);
00316 }
00317 
00318 static isc_result_t
00319 opensslgost_fromdns(dst_key_t *key, isc_buffer_t *data) {
00320         isc_region_t r;
00321         EVP_PKEY *pkey = NULL;
00322         unsigned char der[37 + 64];
00323         const unsigned char *p;
00324 
00325         isc_buffer_remainingregion(data, &r);
00326         if (r.length == 0)
00327                 return (ISC_R_SUCCESS);
00328 
00329         if (r.length != 64)
00330                 return (DST_R_INVALIDPUBLICKEY);
00331         memmove(der, gost_prefix, 37);
00332         memmove(der + 37, r.base, 64);
00333         isc_buffer_forward(data, 64);
00334 
00335         p = der;
00336         if (d2i_PUBKEY(&pkey, &p, (long) sizeof(der)) == NULL)
00337                 return (dst__openssl_toresult2("d2i_PUBKEY",
00338                                                DST_R_OPENSSLFAILURE));
00339         key->keydata.pkey = pkey;
00340         key->key_size = EVP_PKEY_bits(pkey);
00341 
00342         return (ISC_R_SUCCESS);
00343 }
00344 
00345 #ifdef PREFER_GOSTASN1
00346 
00347 static isc_result_t
00348 opensslgost_tofile(const dst_key_t *key, const char *directory) {
00349         EVP_PKEY *pkey;
00350         dst_private_t priv;
00351         isc_result_t result;
00352         unsigned char *der, *p;
00353         int len;
00354 
00355         if (key->keydata.pkey == NULL)
00356                 return (DST_R_NULLKEY);
00357 
00358         if (key->external) {
00359                 priv.nelements = 0;
00360                 return (dst__privstruct_writefile(key, &priv, directory));
00361         }
00362 
00363         pkey = key->keydata.pkey;
00364 
00365         len = i2d_PrivateKey(pkey, NULL);
00366         der = isc_mem_get(key->mctx, (size_t) len);
00367         if (der == NULL)
00368                 return (ISC_R_NOMEMORY);
00369 
00370         p = der;
00371         if (i2d_PrivateKey(pkey, &p) != len) {
00372                 result = dst__openssl_toresult2("i2d_PrivateKey",
00373                                                 DST_R_OPENSSLFAILURE);
00374                 goto fail;
00375         }
00376 
00377         priv.elements[0].tag = TAG_GOST_PRIVASN1;
00378         priv.elements[0].length = len;
00379         priv.elements[0].data = der;
00380         priv.nelements = 1;
00381 
00382         result = dst__privstruct_writefile(key, &priv, directory);
00383  fail:
00384         if (der != NULL)
00385                 isc_mem_put(key->mctx, der, (size_t) len);
00386         return (result);
00387 }
00388 
00389 #else
00390 
00391 static isc_result_t
00392 opensslgost_tofile(const dst_key_t *key, const char *directory) {
00393         EVP_PKEY *pkey;
00394         EC_KEY *eckey;
00395         const BIGNUM *privkey;
00396         dst_private_t priv;
00397         isc_result_t ret;
00398         unsigned char *buf = NULL;
00399 
00400         if (key->keydata.pkey == NULL)
00401                 return (DST_R_NULLKEY);
00402 
00403         if (key->external) {
00404                 priv.nelements = 0;
00405                 return (dst__privstruct_writefile(key, &priv, directory));
00406         }
00407 
00408         pkey = key->keydata.pkey;
00409         eckey = EVP_PKEY_get0(pkey);
00410         if (eckey == NULL)
00411                 return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
00412         privkey = EC_KEY_get0_private_key(eckey);
00413         if (privkey == NULL)
00414                 return (ISC_R_FAILURE);
00415 
00416         buf = isc_mem_get(key->mctx, BN_num_bytes(privkey));
00417         if (buf == NULL)
00418                 return (ISC_R_NOMEMORY);
00419 
00420         priv.elements[0].tag = TAG_GOST_PRIVRAW;
00421         priv.elements[0].length = BN_num_bytes(privkey);
00422         BN_bn2bin(privkey, buf);
00423         priv.elements[0].data = buf;
00424         priv.nelements = 1;
00425 
00426         ret = dst__privstruct_writefile(key, &priv, directory);
00427 
00428         if (buf != NULL)
00429                 isc_mem_put(key->mctx, buf, BN_num_bytes(privkey));
00430         return (ret);
00431 }
00432 #endif
00433 
00434 static unsigned char gost_dummy_key[71] = {
00435         0x30, 0x45, 0x02, 0x01, 0x00, 0x30, 0x1c, 0x06,
00436         0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x13, 0x30,
00437         0x12, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02,
00438         0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02,
00439         0x02, 0x1e, 0x01, 0x04, 0x22, 0x02, 0x20, 0x1b,
00440         0x3f, 0x94, 0xf7, 0x1a, 0x5f, 0x2f, 0xe7, 0xe5,
00441         0x74, 0x0b, 0x8c, 0xd4, 0xb7, 0x18, 0xdd, 0x65,
00442         0x68, 0x26, 0xd1, 0x54, 0xfb, 0x77, 0xba, 0x63,
00443         0x72, 0xd9, 0xf0, 0x63, 0x87, 0xe0, 0xd6
00444 };
00445 
00446 static isc_result_t
00447 opensslgost_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
00448         dst_private_t priv;
00449         isc_result_t ret;
00450         isc_mem_t *mctx = key->mctx;
00451         EVP_PKEY *pkey = NULL;
00452         EC_KEY *eckey;
00453         const EC_POINT *pubkey = NULL;
00454         BIGNUM *privkey = NULL;
00455         const unsigned char *p;
00456 
00457         /* read private key file */
00458         ret = dst__privstruct_parse(key, DST_ALG_ECCGOST, lexer, mctx, &priv);
00459         if (ret != ISC_R_SUCCESS)
00460                 return (ret);
00461 
00462         if (key->external) {
00463                 if (priv.nelements != 0)
00464                         DST_RET(DST_R_INVALIDPRIVATEKEY);
00465                 if (pub == NULL)
00466                         DST_RET(DST_R_INVALIDPRIVATEKEY);
00467                 key->keydata.pkey = pub->keydata.pkey;
00468                 pub->keydata.pkey = NULL;
00469                 key->key_size = pub->key_size;
00470                 dst__privstruct_free(&priv, mctx);
00471                 memset(&priv, 0, sizeof(priv));
00472                 return (ISC_R_SUCCESS);
00473         }
00474 
00475         INSIST((priv.elements[0].tag == TAG_GOST_PRIVASN1) ||
00476                (priv.elements[0].tag == TAG_GOST_PRIVRAW));
00477 
00478         if (priv.elements[0].tag == TAG_GOST_PRIVASN1) {
00479                 p = priv.elements[0].data;
00480                 if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p,
00481                                    (long) priv.elements[0].length) == NULL)
00482                         DST_RET(dst__openssl_toresult2(
00483                                             "d2i_PrivateKey",
00484                                             DST_R_INVALIDPRIVATEKEY));
00485         } else {
00486                 if ((pub != NULL) && (pub->keydata.pkey != NULL)) {
00487                         eckey = EVP_PKEY_get0(pub->keydata.pkey);
00488                         pubkey = EC_KEY_get0_public_key(eckey);
00489                 }
00490 
00491                 privkey = BN_bin2bn(priv.elements[0].data,
00492                                     priv.elements[0].length, NULL);
00493                 if (privkey == NULL)
00494                         DST_RET(ISC_R_NOMEMORY);
00495 
00496                 /* can't create directly the whole key */
00497                 p = gost_dummy_key;
00498                 if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p,
00499                                    (long) sizeof(gost_dummy_key)) == NULL)
00500                         DST_RET(dst__openssl_toresult2(
00501                                             "d2i_PrivateKey",
00502                                             DST_R_INVALIDPRIVATEKEY));
00503 
00504                 eckey = EVP_PKEY_get0(pkey);
00505                 if (eckey == NULL)
00506                         return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
00507                 if (!EC_KEY_set_private_key(eckey, privkey))
00508                         DST_RET(ISC_R_NOMEMORY);
00509 
00510                 /* have to (re)set the public key */
00511 #ifdef notyet
00512                 (void) gost2001_compute_public(eckey);
00513 #else
00514                 if ((pubkey != NULL) && !EC_KEY_set_public_key(eckey, pubkey))
00515                         DST_RET(ISC_R_NOMEMORY);
00516 #endif
00517                 BN_clear_free(privkey);
00518                 privkey = NULL;
00519         }
00520         key->keydata.pkey = pkey;
00521         key->key_size = EVP_PKEY_bits(pkey);
00522         dst__privstruct_free(&priv, mctx);
00523         memset(&priv, 0, sizeof(priv));
00524         return (ISC_R_SUCCESS);
00525 
00526  err:
00527         if (privkey != NULL)
00528                 BN_clear_free(privkey);
00529         if (pkey != NULL)
00530                 EVP_PKEY_free(pkey);
00531         opensslgost_destroy(key);
00532         dst__privstruct_free(&priv, mctx);
00533         memset(&priv, 0, sizeof(priv));
00534         return (ret);
00535 }
00536 
00537 static void
00538 opensslgost_cleanup(void) {
00539         if (e != NULL) {
00540                 ENGINE_finish(e);
00541                 ENGINE_free(e);
00542                 e = NULL;
00543         }
00544 }
00545 
00546 static dst_func_t opensslgost_functions = {
00547         opensslgost_createctx,
00548         NULL, /*%< createctx2 */
00549         opensslgost_destroyctx,
00550         opensslgost_adddata,
00551         opensslgost_sign,
00552         opensslgost_verify,
00553         NULL, /*%< verify2 */
00554         NULL, /*%< computesecret */
00555         opensslgost_compare,
00556         NULL, /*%< paramcompare */
00557         opensslgost_generate,
00558         opensslgost_isprivate,
00559         opensslgost_destroy,
00560         opensslgost_todns,
00561         opensslgost_fromdns,
00562         opensslgost_tofile,
00563         opensslgost_parse,
00564         opensslgost_cleanup,
00565         NULL, /*%< fromlabel */
00566         NULL, /*%< dump */
00567         NULL  /*%< restore */
00568 };
00569 
00570 isc_result_t
00571 dst__opensslgost_init(dst_func_t **funcp) {
00572         isc_result_t ret;
00573 
00574         REQUIRE(funcp != NULL);
00575 
00576         /* check if the gost engine works properly */
00577         e = ENGINE_by_id("gost");
00578         if (e == NULL)
00579                 return (dst__openssl_toresult2("ENGINE_by_id",
00580                                                DST_R_OPENSSLFAILURE));
00581         if (ENGINE_init(e) <= 0) {
00582                 ENGINE_free(e);
00583                 e = NULL;
00584                 return (dst__openssl_toresult2("ENGINE_init",
00585                                                DST_R_OPENSSLFAILURE));
00586         }
00587         /* better than to rely on digest_gost symbol */
00588         opensslgost_digest = ENGINE_get_digest(e, NID_id_GostR3411_94);
00589         if (opensslgost_digest == NULL)
00590                 DST_RET(dst__openssl_toresult2("ENGINE_get_digest",
00591                                                DST_R_OPENSSLFAILURE));
00592         /* from openssl.cnf */
00593         if (ENGINE_register_pkey_asn1_meths(e) <= 0)
00594                 DST_RET(dst__openssl_toresult2(
00595                                 "ENGINE_register_pkey_asn1_meths",
00596                                 DST_R_OPENSSLFAILURE));
00597         if (ENGINE_ctrl_cmd_string(e,
00598                                    "CRYPT_PARAMS",
00599                                    "id-Gost28147-89-CryptoPro-A-ParamSet",
00600                                    0) <= 0)
00601                 DST_RET(dst__openssl_toresult2("ENGINE_ctrl_cmd_string",
00602                                                DST_R_OPENSSLFAILURE));
00603 
00604         if (*funcp == NULL)
00605                 *funcp = &opensslgost_functions;
00606         return (ISC_R_SUCCESS);
00607 
00608  err:
00609         ENGINE_finish(e);
00610         ENGINE_free(e);
00611         e = NULL;
00612         return (ret);
00613 }
00614 
00615 #else /* HAVE_OPENSSL_GOST */
00616 
00617 #include <isc/util.h>
00618 
00619 EMPTY_TRANSLATION_UNIT
00620 
00621 #endif /* HAVE_OPENSSL_GOST */
00622 /*! \file */

Generated on Tue Apr 28 17:40:58 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha