]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/bind9/lib/dns/opensslecdsa_link.c
Update BIND to 9.9.7.
[FreeBSD/stable/9.git] / contrib / bind9 / lib / dns / opensslecdsa_link.c
1 /*
2  * Copyright (C) 2012-2014  Internet Systems Consortium, Inc. ("ISC")
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14  * PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 /* $Id$ */
18
19 #include <config.h>
20
21 #ifdef HAVE_OPENSSL_ECDSA
22
23 #if !defined(HAVE_EVP_SHA256) || !defined(HAVE_EVP_SHA384)
24 #error "ECDSA without EVP for SHA2?"
25 #endif
26
27 #include <isc/entropy.h>
28 #include <isc/mem.h>
29 #include <isc/sha2.h>
30 #include <isc/string.h>
31 #include <isc/util.h>
32
33 #include <dns/keyvalues.h>
34 #include <dst/result.h>
35
36 #include "dst_internal.h"
37 #include "dst_openssl.h"
38 #include "dst_parse.h"
39
40 #include <openssl/err.h>
41 #include <openssl/objects.h>
42 #include <openssl/ecdsa.h>
43 #include <openssl/bn.h>
44
45 #ifndef NID_X9_62_prime256v1
46 #error "P-256 group is not known (NID_X9_62_prime256v1)"
47 #endif
48 #ifndef NID_secp384r1
49 #error "P-384 group is not known (NID_secp384r1)"
50 #endif
51
52 #define DST_RET(a) {ret = a; goto err;}
53
54 static isc_result_t opensslecdsa_todns(const dst_key_t *key,
55                                        isc_buffer_t *data);
56
57 static isc_result_t
58 opensslecdsa_createctx(dst_key_t *key, dst_context_t *dctx) {
59         EVP_MD_CTX *evp_md_ctx;
60         const EVP_MD *type = NULL;
61
62         UNUSED(key);
63         REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 ||
64                 dctx->key->key_alg == DST_ALG_ECDSA384);
65
66         evp_md_ctx = EVP_MD_CTX_create();
67         if (evp_md_ctx == NULL)
68                 return (ISC_R_NOMEMORY);
69         if (dctx->key->key_alg == DST_ALG_ECDSA256)
70                 type = EVP_sha256();
71         else
72                 type = EVP_sha384();
73
74         if (!EVP_DigestInit_ex(evp_md_ctx, type, NULL)) {
75                 EVP_MD_CTX_destroy(evp_md_ctx);
76                 return (dst__openssl_toresult3(dctx->category,
77                                                "EVP_DigestInit_ex",
78                                                ISC_R_FAILURE));
79         }
80
81         dctx->ctxdata.evp_md_ctx = evp_md_ctx;
82
83         return (ISC_R_SUCCESS);
84 }
85
86 static void
87 opensslecdsa_destroyctx(dst_context_t *dctx) {
88         EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
89
90         REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 ||
91                 dctx->key->key_alg == DST_ALG_ECDSA384);
92
93         if (evp_md_ctx != NULL) {
94                 EVP_MD_CTX_destroy(evp_md_ctx);
95                 dctx->ctxdata.evp_md_ctx = NULL;
96         }
97 }
98
99 static isc_result_t
100 opensslecdsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
101         EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
102
103         REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 ||
104                 dctx->key->key_alg == DST_ALG_ECDSA384);
105
106         if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length))
107                 return (dst__openssl_toresult3(dctx->category,
108                                                "EVP_DigestUpdate",
109                                                ISC_R_FAILURE));
110
111         return (ISC_R_SUCCESS);
112 }
113
114 static int
115 BN_bn2bin_fixed(BIGNUM *bn, unsigned char *buf, int size) {
116         int bytes = size - BN_num_bytes(bn);
117
118         while (bytes-- > 0)
119                 *buf++ = 0;
120         BN_bn2bin(bn, buf);
121         return (size);
122 }
123
124 static isc_result_t
125 opensslecdsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
126         isc_result_t ret;
127         dst_key_t *key = dctx->key;
128         isc_region_t r;
129         ECDSA_SIG *ecdsasig;
130         EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
131         EVP_PKEY *pkey = key->keydata.pkey;
132         EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey);
133         unsigned int dgstlen, siglen;
134         unsigned char digest[EVP_MAX_MD_SIZE];
135
136         REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
137                 key->key_alg == DST_ALG_ECDSA384);
138
139         if (eckey == NULL)
140                 return (ISC_R_FAILURE);
141
142         if (key->key_alg == DST_ALG_ECDSA256)
143                 siglen = DNS_SIG_ECDSA256SIZE;
144         else
145                 siglen = DNS_SIG_ECDSA384SIZE;
146
147         isc_buffer_availableregion(sig, &r);
148         if (r.length < siglen)
149                 DST_RET(ISC_R_NOSPACE);
150
151         if (!EVP_DigestFinal(evp_md_ctx, digest, &dgstlen))
152                 DST_RET(dst__openssl_toresult3(dctx->category,
153                                                "EVP_DigestFinal",
154                                                ISC_R_FAILURE));
155
156         ecdsasig = ECDSA_do_sign(digest, dgstlen, eckey);
157         if (ecdsasig == NULL)
158                 DST_RET(dst__openssl_toresult3(dctx->category,
159                                                "ECDSA_do_sign",
160                                                DST_R_SIGNFAILURE));
161         BN_bn2bin_fixed(ecdsasig->r, r.base, siglen / 2);
162         r.base += siglen / 2;
163         BN_bn2bin_fixed(ecdsasig->s, r.base, siglen / 2);
164         r.base += siglen / 2;
165         ECDSA_SIG_free(ecdsasig);
166         isc_buffer_add(sig, siglen);
167         ret = ISC_R_SUCCESS;
168
169  err:
170         if (eckey != NULL)
171                 EC_KEY_free(eckey);
172         return (ret);
173 }
174
175 static isc_result_t
176 opensslecdsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
177         isc_result_t ret;
178         dst_key_t *key = dctx->key;
179         int status;
180         unsigned char *cp = sig->base;
181         ECDSA_SIG *ecdsasig = NULL;
182         EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
183         EVP_PKEY *pkey = key->keydata.pkey;
184         EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey);
185         unsigned int dgstlen, siglen;
186         unsigned char digest[EVP_MAX_MD_SIZE];
187
188         REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
189                 key->key_alg == DST_ALG_ECDSA384);
190
191         if (eckey == NULL)
192                 return (ISC_R_FAILURE);
193
194         if (key->key_alg == DST_ALG_ECDSA256)
195                 siglen = DNS_SIG_ECDSA256SIZE;
196         else
197                 siglen = DNS_SIG_ECDSA384SIZE;
198
199         if (sig->length != siglen)
200                 return (DST_R_VERIFYFAILURE);
201
202         if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &dgstlen))
203                 DST_RET (dst__openssl_toresult3(dctx->category,
204                                                 "EVP_DigestFinal_ex",
205                                                 ISC_R_FAILURE));
206
207         ecdsasig = ECDSA_SIG_new();
208         if (ecdsasig == NULL)
209                 DST_RET (ISC_R_NOMEMORY);
210         if (ecdsasig->r != NULL)
211                 BN_free(ecdsasig->r);
212         ecdsasig->r = BN_bin2bn(cp, siglen / 2, NULL);
213         cp += siglen / 2;
214         if (ecdsasig->s != NULL)
215                 BN_free(ecdsasig->s);
216         ecdsasig->s = BN_bin2bn(cp, siglen / 2, NULL);
217         /* cp += siglen / 2; */
218
219         status = ECDSA_do_verify(digest, dgstlen, ecdsasig, eckey);
220         switch (status) {
221         case 1:
222                 ret = ISC_R_SUCCESS;
223                 break;
224         case 0:
225                 ret = dst__openssl_toresult(DST_R_VERIFYFAILURE);
226                 break;
227         default:
228                 ret = dst__openssl_toresult3(dctx->category,
229                                              "ECDSA_do_verify",
230                                              DST_R_VERIFYFAILURE);
231                 break;
232         }
233
234  err:
235         if (ecdsasig != NULL)
236                 ECDSA_SIG_free(ecdsasig);
237         if (eckey != NULL)
238                 EC_KEY_free(eckey);
239         return (ret);
240 }
241
242 static isc_boolean_t
243 opensslecdsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
244         isc_boolean_t ret;
245         int status;
246         EVP_PKEY *pkey1 = key1->keydata.pkey;
247         EVP_PKEY *pkey2 = key2->keydata.pkey;
248         EC_KEY *eckey1 = NULL;
249         EC_KEY *eckey2 = NULL;
250         const BIGNUM *priv1, *priv2;
251
252         if (pkey1 == NULL && pkey2 == NULL)
253                 return (ISC_TRUE);
254         else if (pkey1 == NULL || pkey2 == NULL)
255                 return (ISC_FALSE);
256
257         eckey1 = EVP_PKEY_get1_EC_KEY(pkey1);
258         eckey2 = EVP_PKEY_get1_EC_KEY(pkey2);
259         if (eckey1 == NULL && eckey2 == NULL) {
260                 DST_RET (ISC_TRUE);
261         } else if (eckey1 == NULL || eckey2 == NULL)
262                 DST_RET (ISC_FALSE);
263
264         status = EVP_PKEY_cmp(pkey1, pkey2);
265         if (status != 1)
266                 DST_RET (ISC_FALSE);
267
268         priv1 = EC_KEY_get0_private_key(eckey1);
269         priv2 = EC_KEY_get0_private_key(eckey2);
270         if (priv1 != NULL || priv2 != NULL) {
271                 if (priv1 == NULL || priv2 == NULL)
272                         DST_RET (ISC_FALSE);
273                 if (BN_cmp(priv1, priv2) != 0)
274                         DST_RET (ISC_FALSE);
275         }
276         ret = ISC_TRUE;
277
278  err:
279         if (eckey1 != NULL)
280                 EC_KEY_free(eckey1);
281         if (eckey2 != NULL)
282                 EC_KEY_free(eckey2);
283         return (ret);
284 }
285
286 static isc_result_t
287 opensslecdsa_generate(dst_key_t *key, int unused, void (*callback)(int)) {
288         isc_result_t ret;
289         EVP_PKEY *pkey;
290         EC_KEY *eckey = NULL;
291         int group_nid;
292
293         REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
294                 key->key_alg == DST_ALG_ECDSA384);
295         UNUSED(unused);
296         UNUSED(callback);
297
298         if (key->key_alg == DST_ALG_ECDSA256) {
299                 group_nid = NID_X9_62_prime256v1;
300                 key->key_size = DNS_KEY_ECDSA256SIZE * 4;
301         } else {
302                 group_nid = NID_secp384r1;
303                 key->key_size = DNS_KEY_ECDSA384SIZE * 4;
304         }
305
306         eckey = EC_KEY_new_by_curve_name(group_nid);
307         if (eckey == NULL)
308                 return (dst__openssl_toresult2("EC_KEY_new_by_curve_name",
309                                                DST_R_OPENSSLFAILURE));
310
311         if (EC_KEY_generate_key(eckey) != 1)
312                 DST_RET (dst__openssl_toresult2("EC_KEY_generate_key",
313                                                 DST_R_OPENSSLFAILURE));
314
315         pkey = EVP_PKEY_new();
316         if (pkey == NULL)
317                 DST_RET (ISC_R_NOMEMORY);
318         if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) {
319                 EVP_PKEY_free(pkey);
320                 DST_RET (ISC_R_FAILURE);
321         }
322         key->keydata.pkey = pkey;
323         ret = ISC_R_SUCCESS;
324
325  err:
326         if (eckey != NULL)
327                 EC_KEY_free(eckey);
328         return (ret);
329 }
330
331 static isc_boolean_t
332 opensslecdsa_isprivate(const dst_key_t *key) {
333         isc_boolean_t ret;
334         EVP_PKEY *pkey = key->keydata.pkey;
335         EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey);
336
337         ret = ISC_TF(eckey != NULL && EC_KEY_get0_private_key(eckey) != NULL);
338         if (eckey != NULL)
339                 EC_KEY_free(eckey);
340         return (ret);
341 }
342
343 static void
344 opensslecdsa_destroy(dst_key_t *key) {
345         EVP_PKEY *pkey = key->keydata.pkey;
346
347         EVP_PKEY_free(pkey);
348         key->keydata.pkey = NULL;
349 }
350
351 static isc_result_t
352 opensslecdsa_todns(const dst_key_t *key, isc_buffer_t *data) {
353         isc_result_t ret;
354         EVP_PKEY *pkey;
355         EC_KEY *eckey = NULL;
356         isc_region_t r;
357         int len;
358         unsigned char *cp;
359         unsigned char buf[DNS_KEY_ECDSA384SIZE + 1];
360
361         REQUIRE(key->keydata.pkey != NULL);
362
363         pkey = key->keydata.pkey;
364         eckey = EVP_PKEY_get1_EC_KEY(pkey);
365         if (eckey == NULL)
366                 return (dst__openssl_toresult(ISC_R_FAILURE));
367         len = i2o_ECPublicKey(eckey, NULL);
368         /* skip form */
369         len--;
370
371         isc_buffer_availableregion(data, &r);
372         if (r.length < (unsigned int) len)
373                 DST_RET (ISC_R_NOSPACE);
374         cp = buf;
375         if (!i2o_ECPublicKey(eckey, &cp))
376                 DST_RET (dst__openssl_toresult(ISC_R_FAILURE));
377         memmove(r.base, buf + 1, len);
378         isc_buffer_add(data, len);
379         ret = ISC_R_SUCCESS;
380
381  err:
382         if (eckey != NULL)
383                 EC_KEY_free(eckey);
384         return (ret);
385 }
386
387 static isc_result_t
388 opensslecdsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
389         isc_result_t ret;
390         EVP_PKEY *pkey;
391         EC_KEY *eckey = NULL;
392         isc_region_t r;
393         int group_nid;
394         unsigned int len;
395         const unsigned char *cp;
396         unsigned char buf[DNS_KEY_ECDSA384SIZE + 1];
397
398         REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
399                 key->key_alg == DST_ALG_ECDSA384);
400
401         if (key->key_alg == DST_ALG_ECDSA256) {
402                 len = DNS_KEY_ECDSA256SIZE;
403                 group_nid = NID_X9_62_prime256v1;
404         } else {
405                 len = DNS_KEY_ECDSA384SIZE;
406                 group_nid = NID_secp384r1;
407         }
408
409         isc_buffer_remainingregion(data, &r);
410         if (r.length == 0)
411                 return (ISC_R_SUCCESS);
412         if (r.length < len)
413                 return (DST_R_INVALIDPUBLICKEY);
414
415         eckey = EC_KEY_new_by_curve_name(group_nid);
416         if (eckey == NULL)
417                 return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
418
419         buf[0] = POINT_CONVERSION_UNCOMPRESSED;
420         memmove(buf + 1, r.base, len);
421         cp = buf;
422         if (o2i_ECPublicKey(&eckey,
423                             (const unsigned char **) &cp,
424                             (long) len + 1) == NULL)
425                 DST_RET (dst__openssl_toresult(DST_R_INVALIDPUBLICKEY));
426         if (EC_KEY_check_key(eckey) != 1)
427                 DST_RET (dst__openssl_toresult(DST_R_INVALIDPUBLICKEY));
428
429         pkey = EVP_PKEY_new();
430         if (pkey == NULL)
431                 DST_RET (ISC_R_NOMEMORY);
432         if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) {
433                 EVP_PKEY_free(pkey);
434                 DST_RET (dst__openssl_toresult(ISC_R_FAILURE));
435         }
436
437         isc_buffer_forward(data, len);
438         key->keydata.pkey = pkey;
439         key->key_size = len * 4;
440         ret = ISC_R_SUCCESS;
441
442  err:
443         if (eckey != NULL)
444                 EC_KEY_free(eckey);
445         return (ret);
446 }
447
448 static isc_result_t
449 opensslecdsa_tofile(const dst_key_t *key, const char *directory) {
450         isc_result_t ret;
451         EVP_PKEY *pkey;
452         EC_KEY *eckey = NULL;
453         const BIGNUM *privkey;
454         dst_private_t priv;
455         unsigned char *buf = NULL;
456
457         if (key->keydata.pkey == NULL)
458                 return (DST_R_NULLKEY);
459
460         if (key->external) {
461                 priv.nelements = 0;
462                 return (dst__privstruct_writefile(key, &priv, directory));
463         }
464
465         pkey = key->keydata.pkey;
466         eckey = EVP_PKEY_get1_EC_KEY(pkey);
467         if (eckey == NULL)
468                 return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
469         privkey = EC_KEY_get0_private_key(eckey);
470         if (privkey == NULL)
471                 DST_RET (ISC_R_FAILURE);
472
473         buf = isc_mem_get(key->mctx, BN_num_bytes(privkey));
474         if (buf == NULL)
475                 DST_RET (ISC_R_NOMEMORY);
476
477         priv.elements[0].tag = TAG_ECDSA_PRIVATEKEY;
478         priv.elements[0].length = BN_num_bytes(privkey);
479         BN_bn2bin(privkey, buf);
480         priv.elements[0].data = buf;
481         priv.nelements = ECDSA_NTAGS;
482         ret = dst__privstruct_writefile(key, &priv, directory);
483
484  err:
485         if (eckey != NULL)
486                 EC_KEY_free(eckey);
487         if (buf != NULL)
488                 isc_mem_put(key->mctx, buf, BN_num_bytes(privkey));
489         return (ret);
490 }
491
492 static isc_result_t
493 ecdsa_check(EC_KEY *eckey, dst_key_t *pub)
494 {
495         isc_result_t ret = ISC_R_FAILURE;
496         EVP_PKEY *pkey;
497         EC_KEY *pubeckey = NULL;
498         const EC_POINT *pubkey;
499
500         if (pub == NULL)
501                 return (ISC_R_SUCCESS);
502         pkey = pub->keydata.pkey;
503         if (pkey == NULL)
504                 return (ISC_R_SUCCESS);
505         pubeckey = EVP_PKEY_get1_EC_KEY(pkey);
506         if (pubeckey == NULL)
507                 return (ISC_R_SUCCESS);
508         pubkey = EC_KEY_get0_public_key(pubeckey);
509         if (pubkey == NULL)
510                 DST_RET (ISC_R_SUCCESS);
511         if (EC_KEY_set_public_key(eckey, pubkey) != 1)
512                 DST_RET (ISC_R_SUCCESS);
513         if (EC_KEY_check_key(eckey) == 1)
514                 DST_RET (ISC_R_SUCCESS);
515
516  err:
517         if (pubeckey != NULL)
518                 EC_KEY_free(pubeckey);
519         return (ret);
520 }
521
522 static isc_result_t
523 opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
524         dst_private_t priv;
525         isc_result_t ret;
526         EVP_PKEY *pkey, *pubpkey;
527         EC_KEY *eckey = NULL, *pubeckey = NULL;
528         const EC_POINT *pubkey;
529         BIGNUM *privkey;
530         int group_nid;
531         isc_mem_t *mctx = key->mctx;
532
533         REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
534                 key->key_alg == DST_ALG_ECDSA384);
535
536         if (key->key_alg == DST_ALG_ECDSA256)
537                 group_nid = NID_X9_62_prime256v1;
538         else
539                 group_nid = NID_secp384r1;
540
541         eckey = EC_KEY_new_by_curve_name(group_nid);
542         if (eckey == NULL)
543                 return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
544
545         /* read private key file */
546         ret = dst__privstruct_parse(key, DST_ALG_ECDSA256, lexer, mctx, &priv);
547         if (ret != ISC_R_SUCCESS)
548                 goto err;
549
550         if (key->external) {
551                 /*
552                  * Copy the public key to this new key.
553                  */
554                 if (pub == NULL)
555                         DST_RET(DST_R_INVALIDPRIVATEKEY);
556                 pubpkey = pub->keydata.pkey;
557                 pubeckey = EVP_PKEY_get1_EC_KEY(pubpkey);
558                 if (pubeckey == NULL)
559                         DST_RET(DST_R_INVALIDPRIVATEKEY);
560                 pubkey = EC_KEY_get0_public_key(pubeckey);
561                 if (pubkey == NULL)
562                         DST_RET(DST_R_INVALIDPRIVATEKEY);
563                 if (EC_KEY_set_public_key(eckey, pubkey) != 1)
564                         DST_RET(DST_R_INVALIDPRIVATEKEY);
565                 if (EC_KEY_check_key(eckey) != 1)
566                         DST_RET(DST_R_INVALIDPRIVATEKEY);
567         } else {
568                 privkey = BN_bin2bn(priv.elements[0].data,
569                                     priv.elements[0].length, NULL);
570                 if (privkey == NULL)
571                         DST_RET(ISC_R_NOMEMORY);
572                 if (!EC_KEY_set_private_key(eckey, privkey))
573                         DST_RET(ISC_R_NOMEMORY);
574                 if (ecdsa_check(eckey, pub) != ISC_R_SUCCESS)
575                         DST_RET(DST_R_INVALIDPRIVATEKEY);
576                 dst__privstruct_free(&priv, mctx);
577                 memset(&priv, 0, sizeof(priv));
578         }
579
580         pkey = EVP_PKEY_new();
581         if (pkey == NULL)
582                 DST_RET (ISC_R_NOMEMORY);
583         if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) {
584                 EVP_PKEY_free(pkey);
585                 DST_RET (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
586         }
587         key->keydata.pkey = pkey;
588         if (key->key_alg == DST_ALG_ECDSA256)
589                 key->key_size = DNS_KEY_ECDSA256SIZE * 4;
590         else
591                 key->key_size = DNS_KEY_ECDSA384SIZE * 4;
592         ret = ISC_R_SUCCESS;
593
594  err:
595         if (eckey != NULL)
596                 EC_KEY_free(eckey);
597         if (pubeckey != NULL)
598                 EC_KEY_free(pubeckey);
599         dst__privstruct_free(&priv, mctx);
600         memset(&priv, 0, sizeof(priv));
601         return (ret);
602 }
603
604 static dst_func_t opensslecdsa_functions = {
605         opensslecdsa_createctx,
606         opensslecdsa_destroyctx,
607         opensslecdsa_adddata,
608         opensslecdsa_sign,
609         opensslecdsa_verify,
610         NULL, /*%< verify2 */
611         NULL, /*%< computesecret */
612         opensslecdsa_compare,
613         NULL, /*%< paramcompare */
614         opensslecdsa_generate,
615         opensslecdsa_isprivate,
616         opensslecdsa_destroy,
617         opensslecdsa_todns,
618         opensslecdsa_fromdns,
619         opensslecdsa_tofile,
620         opensslecdsa_parse,
621         NULL, /*%< cleanup */
622         NULL, /*%< fromlabel */
623         NULL, /*%< dump */
624         NULL, /*%< restore */
625 };
626
627 isc_result_t
628 dst__opensslecdsa_init(dst_func_t **funcp) {
629         REQUIRE(funcp != NULL);
630         if (*funcp == NULL)
631                 *funcp = &opensslecdsa_functions;
632         return (ISC_R_SUCCESS);
633 }
634
635 #else /* HAVE_OPENSSL_ECDSA */
636
637 #include <isc/util.h>
638
639 EMPTY_TRANSLATION_UNIT
640
641 #endif /* HAVE_OPENSSL_ECDSA */
642 /*! \file */