/contrib/bind9/lib/dns/openssldsa_link.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 639 lines · 497 code · 105 blank · 37 comment · 96 complexity · e051905c340c73dcfb44ef1d10fd3868 MD5 · raw file

  1. /*
  2. * Portions Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
  3. * Portions Copyright (C) 1999-2002 Internet Software Consortium.
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
  10. * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  11. * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
  12. * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
  15. * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. *
  17. * Portions Copyright (C) 1995-2000 by Network Associates, Inc.
  18. *
  19. * Permission to use, copy, modify, and/or distribute this software for any
  20. * purpose with or without fee is hereby granted, provided that the above
  21. * copyright notice and this permission notice appear in all copies.
  22. *
  23. * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
  24. * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  25. * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
  26. * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  27. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  28. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
  29. * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  30. */
  31. /* $Id$ */
  32. #ifdef OPENSSL
  33. #ifndef USE_EVP
  34. #define USE_EVP 1
  35. #endif
  36. #include <config.h>
  37. #include <string.h>
  38. #include <isc/entropy.h>
  39. #include <isc/mem.h>
  40. #include <isc/sha1.h>
  41. #include <isc/util.h>
  42. #include <dst/result.h>
  43. #include "dst_internal.h"
  44. #include "dst_openssl.h"
  45. #include "dst_parse.h"
  46. #include <openssl/dsa.h>
  47. static isc_result_t openssldsa_todns(const dst_key_t *key, isc_buffer_t *data);
  48. static isc_result_t
  49. openssldsa_createctx(dst_key_t *key, dst_context_t *dctx) {
  50. #if USE_EVP
  51. EVP_MD_CTX *evp_md_ctx;
  52. UNUSED(key);
  53. evp_md_ctx = EVP_MD_CTX_create();
  54. if (evp_md_ctx == NULL)
  55. return (ISC_R_NOMEMORY);
  56. if (!EVP_DigestInit_ex(evp_md_ctx, EVP_dss1(), NULL)) {
  57. EVP_MD_CTX_destroy(evp_md_ctx);
  58. return (ISC_R_FAILURE);
  59. }
  60. dctx->ctxdata.evp_md_ctx = evp_md_ctx;
  61. return (ISC_R_SUCCESS);
  62. #else
  63. isc_sha1_t *sha1ctx;
  64. UNUSED(key);
  65. sha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_sha1_t));
  66. isc_sha1_init(sha1ctx);
  67. dctx->ctxdata.sha1ctx = sha1ctx;
  68. return (ISC_R_SUCCESS);
  69. #endif
  70. }
  71. static void
  72. openssldsa_destroyctx(dst_context_t *dctx) {
  73. #if USE_EVP
  74. EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
  75. if (evp_md_ctx != NULL) {
  76. EVP_MD_CTX_destroy(evp_md_ctx);
  77. dctx->ctxdata.evp_md_ctx = NULL;
  78. }
  79. #else
  80. isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
  81. if (sha1ctx != NULL) {
  82. isc_sha1_invalidate(sha1ctx);
  83. isc_mem_put(dctx->mctx, sha1ctx, sizeof(isc_sha1_t));
  84. dctx->ctxdata.sha1ctx = NULL;
  85. }
  86. #endif
  87. }
  88. static isc_result_t
  89. openssldsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
  90. #if USE_EVP
  91. EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
  92. if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) {
  93. return (ISC_R_FAILURE);
  94. }
  95. #else
  96. isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
  97. isc_sha1_update(sha1ctx, data->base, data->length);
  98. #endif
  99. return (ISC_R_SUCCESS);
  100. }
  101. static int
  102. BN_bn2bin_fixed(BIGNUM *bn, unsigned char *buf, int size) {
  103. int bytes = size - BN_num_bytes(bn);
  104. while (bytes-- > 0)
  105. *buf++ = 0;
  106. BN_bn2bin(bn, buf);
  107. return (size);
  108. }
  109. static isc_result_t
  110. openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
  111. dst_key_t *key = dctx->key;
  112. DSA *dsa = key->keydata.dsa;
  113. isc_region_t r;
  114. DSA_SIG *dsasig;
  115. #if USE_EVP
  116. EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
  117. EVP_PKEY *pkey;
  118. unsigned char *sigbuf;
  119. const unsigned char *sb;
  120. unsigned int siglen;
  121. #else
  122. isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
  123. unsigned char digest[ISC_SHA1_DIGESTLENGTH];
  124. #endif
  125. isc_buffer_availableregion(sig, &r);
  126. if (r.length < ISC_SHA1_DIGESTLENGTH * 2 + 1)
  127. return (ISC_R_NOSPACE);
  128. #if USE_EVP
  129. pkey = EVP_PKEY_new();
  130. if (pkey == NULL)
  131. return (ISC_R_NOMEMORY);
  132. if (!EVP_PKEY_set1_DSA(pkey, dsa)) {
  133. EVP_PKEY_free(pkey);
  134. return (ISC_R_FAILURE);
  135. }
  136. sigbuf = malloc(EVP_PKEY_size(pkey));
  137. if (sigbuf == NULL) {
  138. EVP_PKEY_free(pkey);
  139. return (ISC_R_NOMEMORY);
  140. }
  141. if (!EVP_SignFinal(evp_md_ctx, sigbuf, &siglen, pkey)) {
  142. EVP_PKEY_free(pkey);
  143. free(sigbuf);
  144. return (ISC_R_FAILURE);
  145. }
  146. INSIST(EVP_PKEY_size(pkey) >= (int) siglen);
  147. EVP_PKEY_free(pkey);
  148. /* Convert from Dss-Sig-Value (RFC2459). */
  149. dsasig = DSA_SIG_new();
  150. if (dsasig == NULL) {
  151. free(sigbuf);
  152. return (ISC_R_NOMEMORY);
  153. }
  154. sb = sigbuf;
  155. if (d2i_DSA_SIG(&dsasig, &sb, (long) siglen) == NULL) {
  156. free(sigbuf);
  157. return (ISC_R_FAILURE);
  158. }
  159. free(sigbuf);
  160. #elif 0
  161. /* Only use EVP for the Digest */
  162. if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &siglen)) {
  163. return (ISC_R_FAILURE);
  164. }
  165. dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa);
  166. if (dsasig == NULL)
  167. return (dst__openssl_toresult(DST_R_SIGNFAILURE));
  168. #else
  169. isc_sha1_final(sha1ctx, digest);
  170. dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa);
  171. if (dsasig == NULL)
  172. return (dst__openssl_toresult(DST_R_SIGNFAILURE));
  173. #endif
  174. *r.base++ = (key->key_size - 512)/64;
  175. BN_bn2bin_fixed(dsasig->r, r.base, ISC_SHA1_DIGESTLENGTH);
  176. r.base += ISC_SHA1_DIGESTLENGTH;
  177. BN_bn2bin_fixed(dsasig->s, r.base, ISC_SHA1_DIGESTLENGTH);
  178. r.base += ISC_SHA1_DIGESTLENGTH;
  179. DSA_SIG_free(dsasig);
  180. isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH * 2 + 1);
  181. return (ISC_R_SUCCESS);
  182. }
  183. static isc_result_t
  184. openssldsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
  185. dst_key_t *key = dctx->key;
  186. DSA *dsa = key->keydata.dsa;
  187. int status = 0;
  188. unsigned char *cp = sig->base;
  189. DSA_SIG *dsasig;
  190. #if USE_EVP
  191. EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
  192. #if 0
  193. EVP_PKEY *pkey;
  194. unsigned char *sigbuf;
  195. #endif
  196. unsigned int siglen;
  197. #else
  198. isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
  199. #endif
  200. unsigned char digest[ISC_SHA1_DIGESTLENGTH];
  201. #if USE_EVP
  202. #if 1
  203. /* Only use EVP for the digest */
  204. if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &siglen)) {
  205. return (ISC_R_FAILURE);
  206. }
  207. #endif
  208. #else
  209. isc_sha1_final(sha1ctx, digest);
  210. #endif
  211. if (sig->length != 2 * ISC_SHA1_DIGESTLENGTH + 1) {
  212. return (DST_R_VERIFYFAILURE);
  213. }
  214. cp++; /*%< Skip T */
  215. dsasig = DSA_SIG_new();
  216. if (dsasig == NULL)
  217. return (ISC_R_NOMEMORY);
  218. dsasig->r = BN_bin2bn(cp, ISC_SHA1_DIGESTLENGTH, NULL);
  219. cp += ISC_SHA1_DIGESTLENGTH;
  220. dsasig->s = BN_bin2bn(cp, ISC_SHA1_DIGESTLENGTH, NULL);
  221. #if 0
  222. pkey = EVP_PKEY_new();
  223. if (pkey == NULL)
  224. return (ISC_R_NOMEMORY);
  225. if (!EVP_PKEY_set1_DSA(pkey, dsa)) {
  226. EVP_PKEY_free(pkey);
  227. return (ISC_R_FAILURE);
  228. }
  229. /* Convert to Dss-Sig-Value (RFC2459). */
  230. sigbuf = malloc(EVP_PKEY_size(pkey) + 50);
  231. if (sigbuf == NULL) {
  232. EVP_PKEY_free(pkey);
  233. return (ISC_R_NOMEMORY);
  234. }
  235. siglen = (unsigned) i2d_DSA_SIG(dsasig, &sigbuf);
  236. INSIST(EVP_PKEY_size(pkey) >= (int) siglen);
  237. status = EVP_VerifyFinal(evp_md_ctx, sigbuf, siglen, pkey);
  238. EVP_PKEY_free(pkey);
  239. free(sigbuf);
  240. #else
  241. status = DSA_do_verify(digest, ISC_SHA1_DIGESTLENGTH, dsasig, dsa);
  242. #endif
  243. DSA_SIG_free(dsasig);
  244. if (status != 1)
  245. return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
  246. return (ISC_R_SUCCESS);
  247. }
  248. static isc_boolean_t
  249. openssldsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
  250. int status;
  251. DSA *dsa1, *dsa2;
  252. dsa1 = key1->keydata.dsa;
  253. dsa2 = key2->keydata.dsa;
  254. if (dsa1 == NULL && dsa2 == NULL)
  255. return (ISC_TRUE);
  256. else if (dsa1 == NULL || dsa2 == NULL)
  257. return (ISC_FALSE);
  258. status = BN_cmp(dsa1->p, dsa2->p) ||
  259. BN_cmp(dsa1->q, dsa2->q) ||
  260. BN_cmp(dsa1->g, dsa2->g) ||
  261. BN_cmp(dsa1->pub_key, dsa2->pub_key);
  262. if (status != 0)
  263. return (ISC_FALSE);
  264. if (dsa1->priv_key != NULL || dsa2->priv_key != NULL) {
  265. if (dsa1->priv_key == NULL || dsa2->priv_key == NULL)
  266. return (ISC_FALSE);
  267. if (BN_cmp(dsa1->priv_key, dsa2->priv_key))
  268. return (ISC_FALSE);
  269. }
  270. return (ISC_TRUE);
  271. }
  272. #if OPENSSL_VERSION_NUMBER > 0x00908000L
  273. static int
  274. progress_cb(int p, int n, BN_GENCB *cb)
  275. {
  276. union {
  277. void *dptr;
  278. void (*fptr)(int);
  279. } u;
  280. UNUSED(n);
  281. u.dptr = cb->arg;
  282. if (u.fptr != NULL)
  283. u.fptr(p);
  284. return (1);
  285. }
  286. #endif
  287. static isc_result_t
  288. openssldsa_generate(dst_key_t *key, int unused, void (*callback)(int)) {
  289. DSA *dsa;
  290. unsigned char rand_array[ISC_SHA1_DIGESTLENGTH];
  291. isc_result_t result;
  292. #if OPENSSL_VERSION_NUMBER > 0x00908000L
  293. BN_GENCB cb;
  294. union {
  295. void *dptr;
  296. void (*fptr)(int);
  297. } u;
  298. #else
  299. UNUSED(callback);
  300. #endif
  301. UNUSED(unused);
  302. result = dst__entropy_getdata(rand_array, sizeof(rand_array),
  303. ISC_FALSE);
  304. if (result != ISC_R_SUCCESS)
  305. return (result);
  306. #if OPENSSL_VERSION_NUMBER > 0x00908000L
  307. dsa = DSA_new();
  308. if (dsa == NULL)
  309. return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
  310. if (callback == NULL) {
  311. BN_GENCB_set_old(&cb, NULL, NULL);
  312. } else {
  313. u.fptr = callback;
  314. BN_GENCB_set(&cb, &progress_cb, u.dptr);
  315. }
  316. if (!DSA_generate_parameters_ex(dsa, key->key_size, rand_array,
  317. ISC_SHA1_DIGESTLENGTH, NULL, NULL,
  318. &cb))
  319. {
  320. DSA_free(dsa);
  321. return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
  322. }
  323. #else
  324. dsa = DSA_generate_parameters(key->key_size, rand_array,
  325. ISC_SHA1_DIGESTLENGTH, NULL, NULL,
  326. NULL, NULL);
  327. if (dsa == NULL)
  328. return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
  329. #endif
  330. if (DSA_generate_key(dsa) == 0) {
  331. DSA_free(dsa);
  332. return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
  333. }
  334. dsa->flags &= ~DSA_FLAG_CACHE_MONT_P;
  335. key->keydata.dsa = dsa;
  336. return (ISC_R_SUCCESS);
  337. }
  338. static isc_boolean_t
  339. openssldsa_isprivate(const dst_key_t *key) {
  340. DSA *dsa = key->keydata.dsa;
  341. return (ISC_TF(dsa != NULL && dsa->priv_key != NULL));
  342. }
  343. static void
  344. openssldsa_destroy(dst_key_t *key) {
  345. DSA *dsa = key->keydata.dsa;
  346. DSA_free(dsa);
  347. key->keydata.dsa = NULL;
  348. }
  349. static isc_result_t
  350. openssldsa_todns(const dst_key_t *key, isc_buffer_t *data) {
  351. DSA *dsa;
  352. isc_region_t r;
  353. int dnslen;
  354. unsigned int t, p_bytes;
  355. REQUIRE(key->keydata.dsa != NULL);
  356. dsa = key->keydata.dsa;
  357. isc_buffer_availableregion(data, &r);
  358. t = (BN_num_bytes(dsa->p) - 64) / 8;
  359. if (t > 8)
  360. return (DST_R_INVALIDPUBLICKEY);
  361. p_bytes = 64 + 8 * t;
  362. dnslen = 1 + (key->key_size * 3)/8 + ISC_SHA1_DIGESTLENGTH;
  363. if (r.length < (unsigned int) dnslen)
  364. return (ISC_R_NOSPACE);
  365. *r.base++ = t;
  366. BN_bn2bin_fixed(dsa->q, r.base, ISC_SHA1_DIGESTLENGTH);
  367. r.base += ISC_SHA1_DIGESTLENGTH;
  368. BN_bn2bin_fixed(dsa->p, r.base, key->key_size/8);
  369. r.base += p_bytes;
  370. BN_bn2bin_fixed(dsa->g, r.base, key->key_size/8);
  371. r.base += p_bytes;
  372. BN_bn2bin_fixed(dsa->pub_key, r.base, key->key_size/8);
  373. r.base += p_bytes;
  374. isc_buffer_add(data, dnslen);
  375. return (ISC_R_SUCCESS);
  376. }
  377. static isc_result_t
  378. openssldsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
  379. DSA *dsa;
  380. isc_region_t r;
  381. unsigned int t, p_bytes;
  382. isc_mem_t *mctx = key->mctx;
  383. UNUSED(mctx);
  384. isc_buffer_remainingregion(data, &r);
  385. if (r.length == 0)
  386. return (ISC_R_SUCCESS);
  387. dsa = DSA_new();
  388. if (dsa == NULL)
  389. return (ISC_R_NOMEMORY);
  390. dsa->flags &= ~DSA_FLAG_CACHE_MONT_P;
  391. t = (unsigned int) *r.base++;
  392. if (t > 8) {
  393. DSA_free(dsa);
  394. return (DST_R_INVALIDPUBLICKEY);
  395. }
  396. p_bytes = 64 + 8 * t;
  397. if (r.length < 1 + ISC_SHA1_DIGESTLENGTH + 3 * p_bytes) {
  398. DSA_free(dsa);
  399. return (DST_R_INVALIDPUBLICKEY);
  400. }
  401. dsa->q = BN_bin2bn(r.base, ISC_SHA1_DIGESTLENGTH, NULL);
  402. r.base += ISC_SHA1_DIGESTLENGTH;
  403. dsa->p = BN_bin2bn(r.base, p_bytes, NULL);
  404. r.base += p_bytes;
  405. dsa->g = BN_bin2bn(r.base, p_bytes, NULL);
  406. r.base += p_bytes;
  407. dsa->pub_key = BN_bin2bn(r.base, p_bytes, NULL);
  408. r.base += p_bytes;
  409. key->key_size = p_bytes * 8;
  410. isc_buffer_forward(data, 1 + ISC_SHA1_DIGESTLENGTH + 3 * p_bytes);
  411. key->keydata.dsa = dsa;
  412. return (ISC_R_SUCCESS);
  413. }
  414. static isc_result_t
  415. openssldsa_tofile(const dst_key_t *key, const char *directory) {
  416. int cnt = 0;
  417. DSA *dsa;
  418. dst_private_t priv;
  419. unsigned char bufs[5][128];
  420. if (key->keydata.dsa == NULL)
  421. return (DST_R_NULLKEY);
  422. dsa = key->keydata.dsa;
  423. priv.elements[cnt].tag = TAG_DSA_PRIME;
  424. priv.elements[cnt].length = BN_num_bytes(dsa->p);
  425. BN_bn2bin(dsa->p, bufs[cnt]);
  426. priv.elements[cnt].data = bufs[cnt];
  427. cnt++;
  428. priv.elements[cnt].tag = TAG_DSA_SUBPRIME;
  429. priv.elements[cnt].length = BN_num_bytes(dsa->q);
  430. BN_bn2bin(dsa->q, bufs[cnt]);
  431. priv.elements[cnt].data = bufs[cnt];
  432. cnt++;
  433. priv.elements[cnt].tag = TAG_DSA_BASE;
  434. priv.elements[cnt].length = BN_num_bytes(dsa->g);
  435. BN_bn2bin(dsa->g, bufs[cnt]);
  436. priv.elements[cnt].data = bufs[cnt];
  437. cnt++;
  438. priv.elements[cnt].tag = TAG_DSA_PRIVATE;
  439. priv.elements[cnt].length = BN_num_bytes(dsa->priv_key);
  440. BN_bn2bin(dsa->priv_key, bufs[cnt]);
  441. priv.elements[cnt].data = bufs[cnt];
  442. cnt++;
  443. priv.elements[cnt].tag = TAG_DSA_PUBLIC;
  444. priv.elements[cnt].length = BN_num_bytes(dsa->pub_key);
  445. BN_bn2bin(dsa->pub_key, bufs[cnt]);
  446. priv.elements[cnt].data = bufs[cnt];
  447. cnt++;
  448. priv.nelements = cnt;
  449. return (dst__privstruct_writefile(key, &priv, directory));
  450. }
  451. static isc_result_t
  452. openssldsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
  453. dst_private_t priv;
  454. isc_result_t ret;
  455. int i;
  456. DSA *dsa = NULL;
  457. isc_mem_t *mctx = key->mctx;
  458. #define DST_RET(a) {ret = a; goto err;}
  459. UNUSED(pub);
  460. /* read private key file */
  461. ret = dst__privstruct_parse(key, DST_ALG_DSA, lexer, mctx, &priv);
  462. if (ret != ISC_R_SUCCESS)
  463. return (ret);
  464. dsa = DSA_new();
  465. if (dsa == NULL)
  466. DST_RET(ISC_R_NOMEMORY);
  467. dsa->flags &= ~DSA_FLAG_CACHE_MONT_P;
  468. key->keydata.dsa = dsa;
  469. for (i=0; i < priv.nelements; i++) {
  470. BIGNUM *bn;
  471. bn = BN_bin2bn(priv.elements[i].data,
  472. priv.elements[i].length, NULL);
  473. if (bn == NULL)
  474. DST_RET(ISC_R_NOMEMORY);
  475. switch (priv.elements[i].tag) {
  476. case TAG_DSA_PRIME:
  477. dsa->p = bn;
  478. break;
  479. case TAG_DSA_SUBPRIME:
  480. dsa->q = bn;
  481. break;
  482. case TAG_DSA_BASE:
  483. dsa->g = bn;
  484. break;
  485. case TAG_DSA_PRIVATE:
  486. dsa->priv_key = bn;
  487. break;
  488. case TAG_DSA_PUBLIC:
  489. dsa->pub_key = bn;
  490. break;
  491. }
  492. }
  493. dst__privstruct_free(&priv, mctx);
  494. key->key_size = BN_num_bits(dsa->p);
  495. return (ISC_R_SUCCESS);
  496. err:
  497. openssldsa_destroy(key);
  498. dst__privstruct_free(&priv, mctx);
  499. memset(&priv, 0, sizeof(priv));
  500. return (ret);
  501. }
  502. static dst_func_t openssldsa_functions = {
  503. openssldsa_createctx,
  504. openssldsa_destroyctx,
  505. openssldsa_adddata,
  506. openssldsa_sign,
  507. openssldsa_verify,
  508. NULL, /*%< computesecret */
  509. openssldsa_compare,
  510. NULL, /*%< paramcompare */
  511. openssldsa_generate,
  512. openssldsa_isprivate,
  513. openssldsa_destroy,
  514. openssldsa_todns,
  515. openssldsa_fromdns,
  516. openssldsa_tofile,
  517. openssldsa_parse,
  518. NULL, /*%< cleanup */
  519. NULL, /*%< fromlabel */
  520. NULL, /*%< dump */
  521. NULL, /*%< restore */
  522. };
  523. isc_result_t
  524. dst__openssldsa_init(dst_func_t **funcp) {
  525. REQUIRE(funcp != NULL);
  526. if (*funcp == NULL)
  527. *funcp = &openssldsa_functions;
  528. return (ISC_R_SUCCESS);
  529. }
  530. #else /* OPENSSL */
  531. #include <isc/util.h>
  532. EMPTY_TRANSLATION_UNIT
  533. #endif /* OPENSSL */
  534. /*! \file */