opensslecdsa_link.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2012-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$ */
00018 
00019 #include <config.h>
00020 
00021 #if defined(OPENSSL) && defined(HAVE_OPENSSL_ECDSA)
00022 
00023 #if !defined(HAVE_EVP_SHA256) || !defined(HAVE_EVP_SHA384)
00024 #error "ECDSA without EVP for SHA2?"
00025 #endif
00026 
00027 #include <isc/entropy.h>
00028 #include <isc/mem.h>
00029 #include <isc/sha2.h>
00030 #include <isc/string.h>
00031 #include <isc/util.h>
00032 
00033 #include <dns/keyvalues.h>
00034 #include <dst/result.h>
00035 
00036 #include "dst_internal.h"
00037 #include "dst_openssl.h"
00038 #include "dst_parse.h"
00039 
00040 #include <openssl/err.h>
00041 #include <openssl/objects.h>
00042 #include <openssl/ecdsa.h>
00043 #include <openssl/bn.h>
00044 
00045 #ifndef NID_X9_62_prime256v1
00046 #error "P-256 group is not known (NID_X9_62_prime256v1)"
00047 #endif
00048 #ifndef NID_secp384r1
00049 #error "P-384 group is not known (NID_secp384r1)"
00050 #endif
00051 
00052 #define DST_RET(a) {ret = a; goto err;}
00053 
00054 static isc_result_t opensslecdsa_todns(const dst_key_t *key,
00055                                        isc_buffer_t *data);
00056 
00057 static isc_result_t
00058 opensslecdsa_createctx(dst_key_t *key, dst_context_t *dctx) {
00059         EVP_MD_CTX *evp_md_ctx;
00060         const EVP_MD *type = NULL;
00061 
00062         UNUSED(key);
00063         REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 ||
00064                 dctx->key->key_alg == DST_ALG_ECDSA384);
00065 
00066         evp_md_ctx = EVP_MD_CTX_create();
00067         if (evp_md_ctx == NULL)
00068                 return (ISC_R_NOMEMORY);
00069         if (dctx->key->key_alg == DST_ALG_ECDSA256)
00070                 type = EVP_sha256();
00071         else
00072                 type = EVP_sha384();
00073 
00074         if (!EVP_DigestInit_ex(evp_md_ctx, type, NULL)) {
00075                 EVP_MD_CTX_destroy(evp_md_ctx);
00076                 return (dst__openssl_toresult3(dctx->category,
00077                                                "EVP_DigestInit_ex",
00078                                                ISC_R_FAILURE));
00079         }
00080 
00081         dctx->ctxdata.evp_md_ctx = evp_md_ctx;
00082 
00083         return (ISC_R_SUCCESS);
00084 }
00085 
00086 static void
00087 opensslecdsa_destroyctx(dst_context_t *dctx) {
00088         EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
00089 
00090         REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 ||
00091                 dctx->key->key_alg == DST_ALG_ECDSA384);
00092 
00093         if (evp_md_ctx != NULL) {
00094                 EVP_MD_CTX_destroy(evp_md_ctx);
00095                 dctx->ctxdata.evp_md_ctx = NULL;
00096         }
00097 }
00098 
00099 static isc_result_t
00100 opensslecdsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
00101         EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
00102 
00103         REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 ||
00104                 dctx->key->key_alg == DST_ALG_ECDSA384);
00105 
00106         if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length))
00107                 return (dst__openssl_toresult3(dctx->category,
00108                                                "EVP_DigestUpdate",
00109                                                ISC_R_FAILURE));
00110 
00111         return (ISC_R_SUCCESS);
00112 }
00113 
00114 static int
00115 BN_bn2bin_fixed(BIGNUM *bn, unsigned char *buf, int size) {
00116         int bytes = size - BN_num_bytes(bn);
00117 
00118         while (bytes-- > 0)
00119                 *buf++ = 0;
00120         BN_bn2bin(bn, buf);
00121         return (size);
00122 }
00123 
00124 static isc_result_t
00125 opensslecdsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
00126         isc_result_t ret;
00127         dst_key_t *key = dctx->key;
00128         isc_region_t r;
00129         ECDSA_SIG *ecdsasig;
00130         EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
00131         EVP_PKEY *pkey = key->keydata.pkey;
00132         EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey);
00133         unsigned int dgstlen, siglen;
00134         unsigned char digest[EVP_MAX_MD_SIZE];
00135 
00136         REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
00137                 key->key_alg == DST_ALG_ECDSA384);
00138 
00139         if (eckey == NULL)
00140                 return (ISC_R_FAILURE);
00141 
00142         if (key->key_alg == DST_ALG_ECDSA256)
00143                 siglen = DNS_SIG_ECDSA256SIZE;
00144         else
00145                 siglen = DNS_SIG_ECDSA384SIZE;
00146 
00147         isc_buffer_availableregion(sig, &r);
00148         if (r.length < siglen)
00149                 DST_RET(ISC_R_NOSPACE);
00150 
00151         if (!EVP_DigestFinal(evp_md_ctx, digest, &dgstlen))
00152                 DST_RET(dst__openssl_toresult3(dctx->category,
00153                                                "EVP_DigestFinal",
00154                                                ISC_R_FAILURE));
00155 
00156         ecdsasig = ECDSA_do_sign(digest, dgstlen, eckey);
00157         if (ecdsasig == NULL)
00158                 DST_RET(dst__openssl_toresult3(dctx->category,
00159                                                "ECDSA_do_sign",
00160                                                DST_R_SIGNFAILURE));
00161         BN_bn2bin_fixed(ecdsasig->r, r.base, siglen / 2);
00162         r.base += siglen / 2;
00163         BN_bn2bin_fixed(ecdsasig->s, r.base, siglen / 2);
00164         r.base += siglen / 2;
00165         ECDSA_SIG_free(ecdsasig);
00166         isc_buffer_add(sig, siglen);
00167         ret = ISC_R_SUCCESS;
00168 
00169  err:
00170         if (eckey != NULL)
00171                 EC_KEY_free(eckey);
00172         return (ret);
00173 }
00174 
00175 static isc_result_t
00176 opensslecdsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
00177         isc_result_t ret;
00178         dst_key_t *key = dctx->key;
00179         int status;
00180         unsigned char *cp = sig->base;
00181         ECDSA_SIG *ecdsasig = NULL;
00182         EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
00183         EVP_PKEY *pkey = key->keydata.pkey;
00184         EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey);
00185         unsigned int dgstlen, siglen;
00186         unsigned char digest[EVP_MAX_MD_SIZE];
00187 
00188         REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
00189                 key->key_alg == DST_ALG_ECDSA384);
00190 
00191         if (eckey == NULL)
00192                 return (ISC_R_FAILURE);
00193 
00194         if (key->key_alg == DST_ALG_ECDSA256)
00195                 siglen = DNS_SIG_ECDSA256SIZE;
00196         else
00197                 siglen = DNS_SIG_ECDSA384SIZE;
00198 
00199         if (sig->length != siglen)
00200                 return (DST_R_VERIFYFAILURE);
00201 
00202         if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &dgstlen))
00203                 DST_RET (dst__openssl_toresult3(dctx->category,
00204                                                 "EVP_DigestFinal_ex",
00205                                                 ISC_R_FAILURE));
00206 
00207         ecdsasig = ECDSA_SIG_new();
00208         if (ecdsasig == NULL)
00209                 DST_RET (ISC_R_NOMEMORY);
00210         if (ecdsasig->r != NULL)
00211                 BN_free(ecdsasig->r);
00212         ecdsasig->r = BN_bin2bn(cp, siglen / 2, NULL);
00213         cp += siglen / 2;
00214         if (ecdsasig->s != NULL)
00215                 BN_free(ecdsasig->s);
00216         ecdsasig->s = BN_bin2bn(cp, siglen / 2, NULL);
00217         /* cp += siglen / 2; */
00218 
00219         status = ECDSA_do_verify(digest, dgstlen, ecdsasig, eckey);
00220         switch (status) {
00221         case 1:
00222                 ret = ISC_R_SUCCESS;
00223                 break;
00224         case 0:
00225                 ret = dst__openssl_toresult(DST_R_VERIFYFAILURE);
00226                 break;
00227         default:
00228                 ret = dst__openssl_toresult3(dctx->category,
00229                                              "ECDSA_do_verify",
00230                                              DST_R_VERIFYFAILURE);
00231                 break;
00232         }
00233 
00234  err:
00235         if (ecdsasig != NULL)
00236                 ECDSA_SIG_free(ecdsasig);
00237         if (eckey != NULL)
00238                 EC_KEY_free(eckey);
00239         return (ret);
00240 }
00241 
00242 static isc_boolean_t
00243 opensslecdsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
00244         isc_boolean_t ret;
00245         int status;
00246         EVP_PKEY *pkey1 = key1->keydata.pkey;
00247         EVP_PKEY *pkey2 = key2->keydata.pkey;
00248         EC_KEY *eckey1 = NULL;
00249         EC_KEY *eckey2 = NULL;
00250         const BIGNUM *priv1, *priv2;
00251 
00252         if (pkey1 == NULL && pkey2 == NULL)
00253                 return (ISC_TRUE);
00254         else if (pkey1 == NULL || pkey2 == NULL)
00255                 return (ISC_FALSE);
00256 
00257         eckey1 = EVP_PKEY_get1_EC_KEY(pkey1);
00258         eckey2 = EVP_PKEY_get1_EC_KEY(pkey2);
00259         if (eckey1 == NULL && eckey2 == NULL) {
00260                 DST_RET (ISC_TRUE);
00261         } else if (eckey1 == NULL || eckey2 == NULL)
00262                 DST_RET (ISC_FALSE);
00263 
00264         status = EVP_PKEY_cmp(pkey1, pkey2);
00265         if (status != 1)
00266                 DST_RET (ISC_FALSE);
00267 
00268         priv1 = EC_KEY_get0_private_key(eckey1);
00269         priv2 = EC_KEY_get0_private_key(eckey2);
00270         if (priv1 != NULL || priv2 != NULL) {
00271                 if (priv1 == NULL || priv2 == NULL)
00272                         DST_RET (ISC_FALSE);
00273                 if (BN_cmp(priv1, priv2) != 0)
00274                         DST_RET (ISC_FALSE);
00275         }
00276         ret = ISC_TRUE;
00277 
00278  err:
00279         if (eckey1 != NULL)
00280                 EC_KEY_free(eckey1);
00281         if (eckey2 != NULL)
00282                 EC_KEY_free(eckey2);
00283         return (ret);
00284 }
00285 
00286 static isc_result_t
00287 opensslecdsa_generate(dst_key_t *key, int unused, void (*callback)(int)) {
00288         isc_result_t ret;
00289         EVP_PKEY *pkey;
00290         EC_KEY *eckey = NULL;
00291         int group_nid;
00292 
00293         REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
00294                 key->key_alg == DST_ALG_ECDSA384);
00295         UNUSED(unused);
00296         UNUSED(callback);
00297 
00298         if (key->key_alg == DST_ALG_ECDSA256) {
00299                 group_nid = NID_X9_62_prime256v1;
00300                 key->key_size = DNS_KEY_ECDSA256SIZE * 4;
00301         } else {
00302                 group_nid = NID_secp384r1;
00303                 key->key_size = DNS_KEY_ECDSA384SIZE * 4;
00304         }
00305 
00306         eckey = EC_KEY_new_by_curve_name(group_nid);
00307         if (eckey == NULL)
00308                 return (dst__openssl_toresult2("EC_KEY_new_by_curve_name",
00309                                                DST_R_OPENSSLFAILURE));
00310 
00311         if (EC_KEY_generate_key(eckey) != 1)
00312                 DST_RET (dst__openssl_toresult2("EC_KEY_generate_key",
00313                                                 DST_R_OPENSSLFAILURE));
00314 
00315         pkey = EVP_PKEY_new();
00316         if (pkey == NULL)
00317                 DST_RET (ISC_R_NOMEMORY);
00318         if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) {
00319                 EVP_PKEY_free(pkey);
00320                 DST_RET (ISC_R_FAILURE);
00321         }
00322         key->keydata.pkey = pkey;
00323         ret = ISC_R_SUCCESS;
00324 
00325  err:
00326         if (eckey != NULL)
00327                 EC_KEY_free(eckey);
00328         return (ret);
00329 }
00330 
00331 static isc_boolean_t
00332 opensslecdsa_isprivate(const dst_key_t *key) {
00333         isc_boolean_t ret;
00334         EVP_PKEY *pkey = key->keydata.pkey;
00335         EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey);
00336 
00337         ret = ISC_TF(eckey != NULL && EC_KEY_get0_private_key(eckey) != NULL);
00338         if (eckey != NULL)
00339                 EC_KEY_free(eckey);
00340         return (ret);
00341 }
00342 
00343 static void
00344 opensslecdsa_destroy(dst_key_t *key) {
00345         EVP_PKEY *pkey = key->keydata.pkey;
00346 
00347         EVP_PKEY_free(pkey);
00348         key->keydata.pkey = NULL;
00349 }
00350 
00351 static isc_result_t
00352 opensslecdsa_todns(const dst_key_t *key, isc_buffer_t *data) {
00353         isc_result_t ret;
00354         EVP_PKEY *pkey;
00355         EC_KEY *eckey = NULL;
00356         isc_region_t r;
00357         int len;
00358         unsigned char *cp;
00359         unsigned char buf[DNS_KEY_ECDSA384SIZE + 1];
00360 
00361         REQUIRE(key->keydata.pkey != NULL);
00362 
00363         pkey = key->keydata.pkey;
00364         eckey = EVP_PKEY_get1_EC_KEY(pkey);
00365         if (eckey == NULL)
00366                 return (dst__openssl_toresult(ISC_R_FAILURE));
00367         len = i2o_ECPublicKey(eckey, NULL);
00368         /* skip form */
00369         len--;
00370 
00371         isc_buffer_availableregion(data, &r);
00372         if (r.length < (unsigned int) len)
00373                 DST_RET (ISC_R_NOSPACE);
00374         cp = buf;
00375         if (!i2o_ECPublicKey(eckey, &cp))
00376                 DST_RET (dst__openssl_toresult(ISC_R_FAILURE));
00377         memmove(r.base, buf + 1, len);
00378         isc_buffer_add(data, len);
00379         ret = ISC_R_SUCCESS;
00380 
00381  err:
00382         if (eckey != NULL)
00383                 EC_KEY_free(eckey);
00384         return (ret);
00385 }
00386 
00387 static isc_result_t
00388 opensslecdsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
00389         isc_result_t ret;
00390         EVP_PKEY *pkey;
00391         EC_KEY *eckey = NULL;
00392         isc_region_t r;
00393         int group_nid;
00394         unsigned int len;
00395         const unsigned char *cp;
00396         unsigned char buf[DNS_KEY_ECDSA384SIZE + 1];
00397 
00398         REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
00399                 key->key_alg == DST_ALG_ECDSA384);
00400 
00401         if (key->key_alg == DST_ALG_ECDSA256) {
00402                 len = DNS_KEY_ECDSA256SIZE;
00403                 group_nid = NID_X9_62_prime256v1;
00404         } else {
00405                 len = DNS_KEY_ECDSA384SIZE;
00406                 group_nid = NID_secp384r1;
00407         }
00408 
00409         isc_buffer_remainingregion(data, &r);
00410         if (r.length == 0)
00411                 return (ISC_R_SUCCESS);
00412         if (r.length < len)
00413                 return (DST_R_INVALIDPUBLICKEY);
00414 
00415         eckey = EC_KEY_new_by_curve_name(group_nid);
00416         if (eckey == NULL)
00417                 return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
00418 
00419         buf[0] = POINT_CONVERSION_UNCOMPRESSED;
00420         memmove(buf + 1, r.base, len);
00421         cp = buf;
00422         if (o2i_ECPublicKey(&eckey,
00423                             (const unsigned char **) &cp,
00424                             (long) len + 1) == NULL)
00425                 DST_RET (dst__openssl_toresult(DST_R_INVALIDPUBLICKEY));
00426         if (EC_KEY_check_key(eckey) != 1)
00427                 DST_RET (dst__openssl_toresult(DST_R_INVALIDPUBLICKEY));
00428 
00429         pkey = EVP_PKEY_new();
00430         if (pkey == NULL)
00431                 DST_RET (ISC_R_NOMEMORY);
00432         if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) {
00433                 EVP_PKEY_free(pkey);
00434                 DST_RET (dst__openssl_toresult(ISC_R_FAILURE));
00435         }
00436 
00437         isc_buffer_forward(data, len);
00438         key->keydata.pkey = pkey;
00439         key->key_size = len * 4;
00440         ret = ISC_R_SUCCESS;
00441 
00442  err:
00443         if (eckey != NULL)
00444                 EC_KEY_free(eckey);
00445         return (ret);
00446 }
00447 
00448 static isc_result_t
00449 opensslecdsa_tofile(const dst_key_t *key, const char *directory) {
00450         isc_result_t ret;
00451         EVP_PKEY *pkey;
00452         EC_KEY *eckey = NULL;
00453         const BIGNUM *privkey;
00454         dst_private_t priv;
00455         unsigned char *buf = NULL;
00456 
00457         if (key->keydata.pkey == NULL)
00458                 return (DST_R_NULLKEY);
00459 
00460         if (key->external) {
00461                 priv.nelements = 0;
00462                 return (dst__privstruct_writefile(key, &priv, directory));
00463         }
00464 
00465         pkey = key->keydata.pkey;
00466         eckey = EVP_PKEY_get1_EC_KEY(pkey);
00467         if (eckey == NULL)
00468                 return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
00469         privkey = EC_KEY_get0_private_key(eckey);
00470         if (privkey == NULL)
00471                 DST_RET (ISC_R_FAILURE);
00472 
00473         buf = isc_mem_get(key->mctx, BN_num_bytes(privkey));
00474         if (buf == NULL)
00475                 DST_RET (ISC_R_NOMEMORY);
00476 
00477         priv.elements[0].tag = TAG_ECDSA_PRIVATEKEY;
00478         priv.elements[0].length = BN_num_bytes(privkey);
00479         BN_bn2bin(privkey, buf);
00480         priv.elements[0].data = buf;
00481         priv.nelements = 1;
00482         ret = dst__privstruct_writefile(key, &priv, directory);
00483 
00484  err:
00485         if (eckey != NULL)
00486                 EC_KEY_free(eckey);
00487         if (buf != NULL)
00488                 isc_mem_put(key->mctx, buf, BN_num_bytes(privkey));
00489         return (ret);
00490 }
00491 
00492 static isc_result_t
00493 ecdsa_check(EC_KEY *eckey, dst_key_t *pub)
00494 {
00495         isc_result_t ret = ISC_R_FAILURE;
00496         EVP_PKEY *pkey;
00497         EC_KEY *pubeckey = NULL;
00498         const EC_POINT *pubkey;
00499 
00500         if (pub == NULL)
00501                 return (ISC_R_SUCCESS);
00502         pkey = pub->keydata.pkey;
00503         if (pkey == NULL)
00504                 return (ISC_R_SUCCESS);
00505         pubeckey = EVP_PKEY_get1_EC_KEY(pkey);
00506         if (pubeckey == NULL)
00507                 return (ISC_R_SUCCESS);
00508         pubkey = EC_KEY_get0_public_key(pubeckey);
00509         if (pubkey == NULL)
00510                 DST_RET (ISC_R_SUCCESS);
00511         if (EC_KEY_set_public_key(eckey, pubkey) != 1)
00512                 DST_RET (ISC_R_SUCCESS);
00513         if (EC_KEY_check_key(eckey) == 1)
00514                 DST_RET (ISC_R_SUCCESS);
00515 
00516  err:
00517         if (pubeckey != NULL)
00518                 EC_KEY_free(pubeckey);
00519         return (ret);
00520 }
00521 
00522 static isc_result_t
00523 opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
00524         dst_private_t priv;
00525         isc_result_t ret;
00526         EVP_PKEY *pkey;
00527         EC_KEY *eckey = NULL;
00528         BIGNUM *privkey = NULL;
00529         int group_nid;
00530         isc_mem_t *mctx = key->mctx;
00531 
00532         REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
00533                 key->key_alg == DST_ALG_ECDSA384);
00534 
00535         /* read private key file */
00536         ret = dst__privstruct_parse(key, DST_ALG_ECDSA256, lexer, mctx, &priv);
00537         if (ret != ISC_R_SUCCESS)
00538                 goto err;
00539 
00540         if (key->external) {
00541                 if (priv.nelements != 0)
00542                         DST_RET(DST_R_INVALIDPRIVATEKEY);
00543                 if (pub == NULL)
00544                         DST_RET(DST_R_INVALIDPRIVATEKEY);
00545                 key->keydata.pkey = pub->keydata.pkey;
00546                 pub->keydata.pkey = NULL;
00547                 dst__privstruct_free(&priv, mctx);
00548                 memset(&priv, 0, sizeof(priv));
00549                 return (ISC_R_SUCCESS);
00550         }
00551 
00552         if (key->key_alg == DST_ALG_ECDSA256)
00553                 group_nid = NID_X9_62_prime256v1;
00554         else
00555                 group_nid = NID_secp384r1;
00556 
00557         eckey = EC_KEY_new_by_curve_name(group_nid);
00558         if (eckey == NULL)
00559                 return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
00560 
00561         privkey = BN_bin2bn(priv.elements[0].data,
00562                             priv.elements[0].length, NULL);
00563         if (privkey == NULL)
00564                 DST_RET(ISC_R_NOMEMORY);
00565         if (!EC_KEY_set_private_key(eckey, privkey))
00566                 DST_RET(ISC_R_NOMEMORY);
00567         if (ecdsa_check(eckey, pub) != ISC_R_SUCCESS)
00568                 DST_RET(DST_R_INVALIDPRIVATEKEY);
00569 
00570         pkey = EVP_PKEY_new();
00571         if (pkey == NULL)
00572                 DST_RET (ISC_R_NOMEMORY);
00573         if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) {
00574                 EVP_PKEY_free(pkey);
00575                 DST_RET (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
00576         }
00577         key->keydata.pkey = pkey;
00578         if (key->key_alg == DST_ALG_ECDSA256)
00579                 key->key_size = DNS_KEY_ECDSA256SIZE * 4;
00580         else
00581                 key->key_size = DNS_KEY_ECDSA384SIZE * 4;
00582         ret = ISC_R_SUCCESS;
00583 
00584  err:
00585         if (privkey != NULL)
00586                 BN_clear_free(privkey);
00587         if (eckey != NULL)
00588                 EC_KEY_free(eckey);
00589         dst__privstruct_free(&priv, mctx);
00590         memset(&priv, 0, sizeof(priv));
00591         return (ret);
00592 }
00593 
00594 static dst_func_t opensslecdsa_functions = {
00595         opensslecdsa_createctx,
00596         NULL, /*%< createctx2 */
00597         opensslecdsa_destroyctx,
00598         opensslecdsa_adddata,
00599         opensslecdsa_sign,
00600         opensslecdsa_verify,
00601         NULL, /*%< verify2 */
00602         NULL, /*%< computesecret */
00603         opensslecdsa_compare,
00604         NULL, /*%< paramcompare */
00605         opensslecdsa_generate,
00606         opensslecdsa_isprivate,
00607         opensslecdsa_destroy,
00608         opensslecdsa_todns,
00609         opensslecdsa_fromdns,
00610         opensslecdsa_tofile,
00611         opensslecdsa_parse,
00612         NULL, /*%< cleanup */
00613         NULL, /*%< fromlabel */
00614         NULL, /*%< dump */
00615         NULL, /*%< restore */
00616 };
00617 
00618 isc_result_t
00619 dst__opensslecdsa_init(dst_func_t **funcp) {
00620         REQUIRE(funcp != NULL);
00621         if (*funcp == NULL)
00622                 *funcp = &opensslecdsa_functions;
00623         return (ISC_R_SUCCESS);
00624 }
00625 
00626 #else /* HAVE_OPENSSL_ECDSA */
00627 
00628 #include <isc/util.h>
00629 
00630 EMPTY_TRANSLATION_UNIT
00631 
00632 #endif /* HAVE_OPENSSL_ECDSA */
00633 /*! \file */

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