Remove building with NOCRYPTO option
[minix.git] / external / bsd / bind / dist / lib / dns / openssldsa_link.c
blob00be7da0ec8e5429b796862c3dfa34b0c225915c
1 /* $NetBSD: openssldsa_link.c,v 1.10 2015/09/03 07:33:34 christos Exp $ */
3 /*
4 * Portions Copyright (C) 2004-2009, 2011-2014 Internet Systems Consortium, Inc. ("ISC")
5 * Portions Copyright (C) 1999-2002 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
12 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
13 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
14 * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
17 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 * Portions Copyright (C) 1995-2000 by Network Associates, Inc.
21 * Permission to use, copy, modify, and/or distribute this software for any
22 * purpose with or without fee is hereby granted, provided that the above
23 * copyright notice and this permission notice appear in all copies.
25 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
26 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
27 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
28 * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
29 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
30 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
31 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
34 #ifdef OPENSSL
35 #ifndef USE_EVP
36 #define USE_EVP 1
37 #endif
39 #include <config.h>
41 #include <string.h>
43 #include <isc/entropy.h>
44 #include <isc/mem.h>
45 #include <isc/sha1.h>
46 #include <isc/util.h>
48 #include <dst/result.h>
50 #include "dst_internal.h"
51 #include "dst_openssl.h"
52 #include "dst_parse.h"
54 #include <openssl/dsa.h>
56 static isc_result_t openssldsa_todns(const dst_key_t *key, isc_buffer_t *data);
58 static isc_result_t
59 openssldsa_createctx(dst_key_t *key, dst_context_t *dctx) {
60 #if USE_EVP
61 EVP_MD_CTX *evp_md_ctx;
63 UNUSED(key);
65 evp_md_ctx = EVP_MD_CTX_create();
66 if (evp_md_ctx == NULL)
67 return (ISC_R_NOMEMORY);
69 if (!EVP_DigestInit_ex(evp_md_ctx, EVP_dss1(), NULL)) {
70 EVP_MD_CTX_destroy(evp_md_ctx);
71 return (ISC_R_FAILURE);
74 dctx->ctxdata.evp_md_ctx = evp_md_ctx;
76 return (ISC_R_SUCCESS);
77 #else
78 isc_sha1_t *sha1ctx;
80 UNUSED(key);
82 sha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_sha1_t));
83 isc_sha1_init(sha1ctx);
84 dctx->ctxdata.sha1ctx = sha1ctx;
85 return (ISC_R_SUCCESS);
86 #endif
89 static void
90 openssldsa_destroyctx(dst_context_t *dctx) {
91 #if USE_EVP
92 EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
94 if (evp_md_ctx != NULL) {
95 EVP_MD_CTX_destroy(evp_md_ctx);
96 dctx->ctxdata.evp_md_ctx = NULL;
98 #else
99 isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
101 if (sha1ctx != NULL) {
102 isc_sha1_invalidate(sha1ctx);
103 isc_mem_put(dctx->mctx, sha1ctx, sizeof(isc_sha1_t));
104 dctx->ctxdata.sha1ctx = NULL;
106 #endif
109 static isc_result_t
110 openssldsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
111 #if USE_EVP
112 EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
114 if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) {
115 return (ISC_R_FAILURE);
117 #else
118 isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
120 isc_sha1_update(sha1ctx, data->base, data->length);
121 #endif
122 return (ISC_R_SUCCESS);
125 static int
126 BN_bn2bin_fixed(BIGNUM *bn, unsigned char *buf, int size) {
127 int bytes = size - BN_num_bytes(bn);
128 while (bytes-- > 0)
129 *buf++ = 0;
130 BN_bn2bin(bn, buf);
131 return (size);
134 static isc_result_t
135 openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
136 dst_key_t *key = dctx->key;
137 DSA *dsa = key->keydata.dsa;
138 isc_region_t r;
139 DSA_SIG *dsasig;
140 unsigned int klen;
141 #if USE_EVP
142 EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
143 EVP_PKEY *pkey;
144 unsigned char *sigbuf;
145 const unsigned char *sb;
146 unsigned int siglen;
147 #else
148 isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
149 unsigned char digest[ISC_SHA1_DIGESTLENGTH];
150 #endif
152 isc_buffer_availableregion(sig, &r);
153 if (r.length < ISC_SHA1_DIGESTLENGTH * 2 + 1)
154 return (ISC_R_NOSPACE);
156 #if USE_EVP
157 pkey = EVP_PKEY_new();
158 if (pkey == NULL)
159 return (ISC_R_NOMEMORY);
160 if (!EVP_PKEY_set1_DSA(pkey, dsa)) {
161 EVP_PKEY_free(pkey);
162 return (ISC_R_FAILURE);
164 sigbuf = malloc(EVP_PKEY_size(pkey));
165 if (sigbuf == NULL) {
166 EVP_PKEY_free(pkey);
167 return (ISC_R_NOMEMORY);
169 if (!EVP_SignFinal(evp_md_ctx, sigbuf, &siglen, pkey)) {
170 EVP_PKEY_free(pkey);
171 free(sigbuf);
172 return (dst__openssl_toresult3(dctx->category,
173 "EVP_SignFinal",
174 ISC_R_FAILURE));
176 INSIST(EVP_PKEY_size(pkey) >= (int) siglen);
177 EVP_PKEY_free(pkey);
178 /* Convert from Dss-Sig-Value (RFC2459). */
179 dsasig = DSA_SIG_new();
180 if (dsasig == NULL) {
181 free(sigbuf);
182 return (ISC_R_NOMEMORY);
184 sb = sigbuf;
185 if (d2i_DSA_SIG(&dsasig, &sb, (long) siglen) == NULL) {
186 free(sigbuf);
187 return (dst__openssl_toresult3(dctx->category,
188 "d2i_DSA_SIG",
189 ISC_R_FAILURE));
191 free(sigbuf);
193 #elif 0
194 /* Only use EVP for the Digest */
195 if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &siglen)) {
196 return (dst__openssl_toresult3(dctx->category,
197 "EVP_DigestFinal_ex",
198 ISC_R_FAILURE));
200 dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa);
201 if (dsasig == NULL)
202 return (dst__openssl_toresult3(dctx->category,
203 "DSA_do_sign",
204 DST_R_SIGNFAILURE));
205 #else
206 isc_sha1_final(sha1ctx, digest);
208 dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa);
209 if (dsasig == NULL)
210 return (dst__openssl_toresult3(dctx->category,
211 "DSA_do_sign",
212 DST_R_SIGNFAILURE));
213 #endif
215 klen = (key->key_size - 512)/64;
216 if (klen > 255)
217 return (ISC_R_FAILURE);
218 *r.base = klen;
219 isc_region_consume(&r, 1);
221 BN_bn2bin_fixed(dsasig->r, r.base, ISC_SHA1_DIGESTLENGTH);
222 isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH);
223 BN_bn2bin_fixed(dsasig->s, r.base, ISC_SHA1_DIGESTLENGTH);
224 isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH);
225 DSA_SIG_free(dsasig);
226 isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH * 2 + 1);
228 return (ISC_R_SUCCESS);
231 static isc_result_t
232 openssldsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
233 dst_key_t *key = dctx->key;
234 DSA *dsa = key->keydata.dsa;
235 int status = 0;
236 unsigned char *cp = sig->base;
237 DSA_SIG *dsasig;
238 #if USE_EVP
239 EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
240 #if 0
241 EVP_PKEY *pkey;
242 unsigned char *sigbuf;
243 #endif
244 unsigned int siglen;
245 #else
246 isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
247 #endif
248 unsigned char digest[ISC_SHA1_DIGESTLENGTH];
251 #if USE_EVP
252 #if 1
253 /* Only use EVP for the digest */
254 if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &siglen)) {
255 return (ISC_R_FAILURE);
257 #endif
258 #else
259 isc_sha1_final(sha1ctx, digest);
260 #endif
262 if (sig->length != 2 * ISC_SHA1_DIGESTLENGTH + 1) {
263 return (DST_R_VERIFYFAILURE);
266 cp++; /*%< Skip T */
267 dsasig = DSA_SIG_new();
268 if (dsasig == NULL)
269 return (ISC_R_NOMEMORY);
270 dsasig->r = BN_bin2bn(cp, ISC_SHA1_DIGESTLENGTH, NULL);
271 cp += ISC_SHA1_DIGESTLENGTH;
272 dsasig->s = BN_bin2bn(cp, ISC_SHA1_DIGESTLENGTH, NULL);
274 #if 0
275 pkey = EVP_PKEY_new();
276 if (pkey == NULL)
277 return (ISC_R_NOMEMORY);
278 if (!EVP_PKEY_set1_DSA(pkey, dsa)) {
279 EVP_PKEY_free(pkey);
280 return (ISC_R_FAILURE);
282 /* Convert to Dss-Sig-Value (RFC2459). */
283 sigbuf = malloc(EVP_PKEY_size(pkey) + 50);
284 if (sigbuf == NULL) {
285 EVP_PKEY_free(pkey);
286 return (ISC_R_NOMEMORY);
288 siglen = (unsigned) i2d_DSA_SIG(dsasig, &sigbuf);
289 INSIST(EVP_PKEY_size(pkey) >= (int) siglen);
290 status = EVP_VerifyFinal(evp_md_ctx, sigbuf, siglen, pkey);
291 EVP_PKEY_free(pkey);
292 free(sigbuf);
293 #else
294 status = DSA_do_verify(digest, ISC_SHA1_DIGESTLENGTH, dsasig, dsa);
295 #endif
296 DSA_SIG_free(dsasig);
297 switch (status) {
298 case 1:
299 return (ISC_R_SUCCESS);
300 case 0:
301 return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
302 default:
303 return (dst__openssl_toresult3(dctx->category,
304 "DSA_do_verify",
305 DST_R_VERIFYFAILURE));
309 static isc_boolean_t
310 openssldsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
311 int status;
312 DSA *dsa1, *dsa2;
314 dsa1 = key1->keydata.dsa;
315 dsa2 = key2->keydata.dsa;
317 if (dsa1 == NULL && dsa2 == NULL)
318 return (ISC_TRUE);
319 else if (dsa1 == NULL || dsa2 == NULL)
320 return (ISC_FALSE);
322 status = BN_cmp(dsa1->p, dsa2->p) ||
323 BN_cmp(dsa1->q, dsa2->q) ||
324 BN_cmp(dsa1->g, dsa2->g) ||
325 BN_cmp(dsa1->pub_key, dsa2->pub_key);
327 if (status != 0)
328 return (ISC_FALSE);
330 if (dsa1->priv_key != NULL || dsa2->priv_key != NULL) {
331 if (dsa1->priv_key == NULL || dsa2->priv_key == NULL)
332 return (ISC_FALSE);
333 if (BN_cmp(dsa1->priv_key, dsa2->priv_key))
334 return (ISC_FALSE);
336 return (ISC_TRUE);
339 #if OPENSSL_VERSION_NUMBER > 0x00908000L
340 static int
341 progress_cb(int p, int n, BN_GENCB *cb)
343 union {
344 void *dptr;
345 void (*fptr)(int);
346 } u;
348 UNUSED(n);
350 u.dptr = cb->arg;
351 if (u.fptr != NULL)
352 u.fptr(p);
353 return (1);
355 #endif
357 static isc_result_t
358 openssldsa_generate(dst_key_t *key, int unused, void (*callback)(int)) {
359 DSA *dsa;
360 unsigned char rand_array[ISC_SHA1_DIGESTLENGTH];
361 isc_result_t result;
362 #if OPENSSL_VERSION_NUMBER > 0x00908000L
363 BN_GENCB cb;
364 union {
365 void *dptr;
366 void (*fptr)(int);
367 } u;
369 #else
371 UNUSED(callback);
372 #endif
373 UNUSED(unused);
375 result = dst__entropy_getdata(rand_array, sizeof(rand_array),
376 ISC_FALSE);
377 if (result != ISC_R_SUCCESS)
378 return (result);
380 #if OPENSSL_VERSION_NUMBER > 0x00908000L
381 dsa = DSA_new();
382 if (dsa == NULL)
383 return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
385 if (callback == NULL) {
386 BN_GENCB_set_old(&cb, NULL, NULL);
387 } else {
388 u.fptr = callback;
389 BN_GENCB_set(&cb, &progress_cb, u.dptr);
392 if (!DSA_generate_parameters_ex(dsa, key->key_size, rand_array,
393 ISC_SHA1_DIGESTLENGTH, NULL, NULL,
394 &cb))
396 DSA_free(dsa);
397 return (dst__openssl_toresult2("DSA_generate_parameters_ex",
398 DST_R_OPENSSLFAILURE));
400 #else
401 dsa = DSA_generate_parameters(key->key_size, rand_array,
402 ISC_SHA1_DIGESTLENGTH, NULL, NULL,
403 NULL, NULL);
404 if (dsa == NULL)
405 return (dst__openssl_toresult2("DSA_generate_parameters",
406 DST_R_OPENSSLFAILURE));
407 #endif
409 if (DSA_generate_key(dsa) == 0) {
410 DSA_free(dsa);
411 return (dst__openssl_toresult2("DSA_generate_key",
412 DST_R_OPENSSLFAILURE));
414 dsa->flags &= ~DSA_FLAG_CACHE_MONT_P;
416 key->keydata.dsa = dsa;
418 return (ISC_R_SUCCESS);
421 static isc_boolean_t
422 openssldsa_isprivate(const dst_key_t *key) {
423 DSA *dsa = key->keydata.dsa;
424 return (ISC_TF(dsa != NULL && dsa->priv_key != NULL));
427 static void
428 openssldsa_destroy(dst_key_t *key) {
429 DSA *dsa = key->keydata.dsa;
430 DSA_free(dsa);
431 key->keydata.dsa = NULL;
435 static isc_result_t
436 openssldsa_todns(const dst_key_t *key, isc_buffer_t *data) {
437 DSA *dsa;
438 isc_region_t r;
439 int dnslen;
440 unsigned int t, p_bytes;
442 REQUIRE(key->keydata.dsa != NULL);
444 dsa = key->keydata.dsa;
446 isc_buffer_availableregion(data, &r);
448 t = (BN_num_bytes(dsa->p) - 64) / 8;
449 if (t > 8)
450 return (DST_R_INVALIDPUBLICKEY);
451 p_bytes = 64 + 8 * t;
453 dnslen = 1 + (key->key_size * 3)/8 + ISC_SHA1_DIGESTLENGTH;
454 if (r.length < (unsigned int) dnslen)
455 return (ISC_R_NOSPACE);
457 *r.base = t;
458 isc_region_consume(&r, 1);
459 BN_bn2bin_fixed(dsa->q, r.base, ISC_SHA1_DIGESTLENGTH);
460 isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH);
461 BN_bn2bin_fixed(dsa->p, r.base, key->key_size/8);
462 isc_region_consume(&r, p_bytes);
463 BN_bn2bin_fixed(dsa->g, r.base, key->key_size/8);
464 isc_region_consume(&r, p_bytes);
465 BN_bn2bin_fixed(dsa->pub_key, r.base, key->key_size/8);
466 isc_region_consume(&r, p_bytes);
468 isc_buffer_add(data, dnslen);
470 return (ISC_R_SUCCESS);
473 static isc_result_t
474 openssldsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
475 DSA *dsa;
476 isc_region_t r;
477 unsigned int t, p_bytes;
478 isc_mem_t *mctx = key->mctx;
480 UNUSED(mctx);
482 isc_buffer_remainingregion(data, &r);
483 if (r.length == 0)
484 return (ISC_R_SUCCESS);
486 dsa = DSA_new();
487 if (dsa == NULL)
488 return (ISC_R_NOMEMORY);
489 dsa->flags &= ~DSA_FLAG_CACHE_MONT_P;
491 t = (unsigned int) *r.base;
492 isc_region_consume(&r, 1);
493 if (t > 8) {
494 DSA_free(dsa);
495 return (DST_R_INVALIDPUBLICKEY);
497 p_bytes = 64 + 8 * t;
499 if (r.length < ISC_SHA1_DIGESTLENGTH + 3 * p_bytes) {
500 DSA_free(dsa);
501 return (DST_R_INVALIDPUBLICKEY);
504 dsa->q = BN_bin2bn(r.base, ISC_SHA1_DIGESTLENGTH, NULL);
505 isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH);
507 dsa->p = BN_bin2bn(r.base, p_bytes, NULL);
508 isc_region_consume(&r, p_bytes);
510 dsa->g = BN_bin2bn(r.base, p_bytes, NULL);
511 isc_region_consume(&r, p_bytes);
513 dsa->pub_key = BN_bin2bn(r.base, p_bytes, NULL);
514 isc_region_consume(&r, p_bytes);
516 key->key_size = p_bytes * 8;
518 isc_buffer_forward(data, 1 + ISC_SHA1_DIGESTLENGTH + 3 * p_bytes);
520 key->keydata.dsa = dsa;
522 return (ISC_R_SUCCESS);
526 static isc_result_t
527 openssldsa_tofile(const dst_key_t *key, const char *directory) {
528 int cnt = 0;
529 DSA *dsa;
530 dst_private_t priv;
531 unsigned char bufs[5][128];
533 if (key->keydata.dsa == NULL)
534 return (DST_R_NULLKEY);
536 if (key->external) {
537 priv.nelements = 0;
538 return (dst__privstruct_writefile(key, &priv, directory));
541 dsa = key->keydata.dsa;
543 priv.elements[cnt].tag = TAG_DSA_PRIME;
544 priv.elements[cnt].length = BN_num_bytes(dsa->p);
545 BN_bn2bin(dsa->p, bufs[cnt]);
546 priv.elements[cnt].data = bufs[cnt];
547 cnt++;
549 priv.elements[cnt].tag = TAG_DSA_SUBPRIME;
550 priv.elements[cnt].length = BN_num_bytes(dsa->q);
551 BN_bn2bin(dsa->q, bufs[cnt]);
552 priv.elements[cnt].data = bufs[cnt];
553 cnt++;
555 priv.elements[cnt].tag = TAG_DSA_BASE;
556 priv.elements[cnt].length = BN_num_bytes(dsa->g);
557 BN_bn2bin(dsa->g, bufs[cnt]);
558 priv.elements[cnt].data = bufs[cnt];
559 cnt++;
561 priv.elements[cnt].tag = TAG_DSA_PRIVATE;
562 priv.elements[cnt].length = BN_num_bytes(dsa->priv_key);
563 BN_bn2bin(dsa->priv_key, bufs[cnt]);
564 priv.elements[cnt].data = bufs[cnt];
565 cnt++;
567 priv.elements[cnt].tag = TAG_DSA_PUBLIC;
568 priv.elements[cnt].length = BN_num_bytes(dsa->pub_key);
569 BN_bn2bin(dsa->pub_key, bufs[cnt]);
570 priv.elements[cnt].data = bufs[cnt];
571 cnt++;
573 priv.nelements = cnt;
574 return (dst__privstruct_writefile(key, &priv, directory));
577 static isc_result_t
578 openssldsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
579 dst_private_t priv;
580 isc_result_t ret;
581 int i;
582 DSA *dsa = NULL;
583 isc_mem_t *mctx = key->mctx;
584 #define DST_RET(a) {ret = a; goto err;}
586 /* read private key file */
587 ret = dst__privstruct_parse(key, DST_ALG_DSA, lexer, mctx, &priv);
588 if (ret != ISC_R_SUCCESS)
589 return (ret);
591 if (key->external) {
592 if (priv.nelements != 0)
593 DST_RET(DST_R_INVALIDPRIVATEKEY);
594 if (pub == NULL)
595 DST_RET(DST_R_INVALIDPRIVATEKEY);
596 key->keydata.pkey = pub->keydata.pkey;
597 pub->keydata.pkey = NULL;
598 key->key_size = pub->key_size;
599 dst__privstruct_free(&priv, mctx);
600 memset(&priv, 0, sizeof(priv));
601 return (ISC_R_SUCCESS);
604 dsa = DSA_new();
605 if (dsa == NULL)
606 DST_RET(ISC_R_NOMEMORY);
607 dsa->flags &= ~DSA_FLAG_CACHE_MONT_P;
608 key->keydata.dsa = dsa;
610 for (i = 0; i < priv.nelements; i++) {
611 BIGNUM *bn;
612 bn = BN_bin2bn(priv.elements[i].data,
613 priv.elements[i].length, NULL);
614 if (bn == NULL)
615 DST_RET(ISC_R_NOMEMORY);
617 switch (priv.elements[i].tag) {
618 case TAG_DSA_PRIME:
619 dsa->p = bn;
620 break;
621 case TAG_DSA_SUBPRIME:
622 dsa->q = bn;
623 break;
624 case TAG_DSA_BASE:
625 dsa->g = bn;
626 break;
627 case TAG_DSA_PRIVATE:
628 dsa->priv_key = bn;
629 break;
630 case TAG_DSA_PUBLIC:
631 dsa->pub_key = bn;
632 break;
635 dst__privstruct_free(&priv, mctx);
636 memset(&priv, 0, sizeof(priv));
637 key->key_size = BN_num_bits(dsa->p);
638 return (ISC_R_SUCCESS);
640 err:
641 openssldsa_destroy(key);
642 dst__privstruct_free(&priv, mctx);
643 memset(&priv, 0, sizeof(priv));
644 return (ret);
647 static dst_func_t openssldsa_functions = {
648 openssldsa_createctx,
649 NULL, /*%< createctx2 */
650 openssldsa_destroyctx,
651 openssldsa_adddata,
652 openssldsa_sign,
653 openssldsa_verify,
654 NULL, /*%< verify2 */
655 NULL, /*%< computesecret */
656 openssldsa_compare,
657 NULL, /*%< paramcompare */
658 openssldsa_generate,
659 openssldsa_isprivate,
660 openssldsa_destroy,
661 openssldsa_todns,
662 openssldsa_fromdns,
663 openssldsa_tofile,
664 openssldsa_parse,
665 NULL, /*%< cleanup */
666 NULL, /*%< fromlabel */
667 NULL, /*%< dump */
668 NULL, /*%< restore */
671 isc_result_t
672 dst__openssldsa_init(dst_func_t **funcp) {
673 REQUIRE(funcp != NULL);
674 if (*funcp == NULL)
675 *funcp = &openssldsa_functions;
676 return (ISC_R_SUCCESS);
679 #else /* OPENSSL */
681 #include <isc/util.h>
683 EMPTY_TRANSLATION_UNIT
685 #endif /* OPENSSL */
686 /*! \file */