00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 #ifdef OPENSSL
00035 #ifndef USE_EVP
00036 #define USE_EVP 1
00037 #endif
00038 
00039 #include <config.h>
00040 
00041 #include <string.h>
00042 
00043 #include <isc/entropy.h>
00044 #include <isc/mem.h>
00045 #include <isc/sha1.h>
00046 #include <isc/util.h>
00047 
00048 #include <dst/result.h>
00049 
00050 #include "dst_internal.h"
00051 #include "dst_openssl.h"
00052 #include "dst_parse.h"
00053 
00054 #include <openssl/dsa.h>
00055 
00056 static isc_result_t openssldsa_todns(const dst_key_t *key, isc_buffer_t *data);
00057 
00058 static isc_result_t
00059 openssldsa_createctx(dst_key_t *key, dst_context_t *dctx) {
00060 #if USE_EVP
00061         EVP_MD_CTX *evp_md_ctx;
00062 
00063         UNUSED(key);
00064 
00065         evp_md_ctx = EVP_MD_CTX_create();
00066         if (evp_md_ctx == NULL)
00067                 return (ISC_R_NOMEMORY);
00068 
00069         if (!EVP_DigestInit_ex(evp_md_ctx, EVP_dss1(), NULL)) {
00070                 EVP_MD_CTX_destroy(evp_md_ctx);
00071                         return (ISC_R_FAILURE);
00072         }
00073 
00074         dctx->ctxdata.evp_md_ctx = evp_md_ctx;
00075 
00076         return (ISC_R_SUCCESS);
00077 #else
00078         isc_sha1_t *sha1ctx;
00079 
00080         UNUSED(key);
00081 
00082         sha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_sha1_t));
00083         isc_sha1_init(sha1ctx);
00084         dctx->ctxdata.sha1ctx = sha1ctx;
00085         return (ISC_R_SUCCESS);
00086 #endif
00087 }
00088 
00089 static void
00090 openssldsa_destroyctx(dst_context_t *dctx) {
00091 #if USE_EVP
00092         EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
00093 
00094         if (evp_md_ctx != NULL) {
00095                 EVP_MD_CTX_destroy(evp_md_ctx);
00096                 dctx->ctxdata.evp_md_ctx = NULL;
00097         }
00098 #else
00099         isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
00100 
00101         if (sha1ctx != NULL) {
00102                 isc_sha1_invalidate(sha1ctx);
00103                 isc_mem_put(dctx->mctx, sha1ctx, sizeof(isc_sha1_t));
00104                 dctx->ctxdata.sha1ctx = NULL;
00105         }
00106 #endif
00107 }
00108 
00109 static isc_result_t
00110 openssldsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
00111 #if USE_EVP
00112         EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
00113 
00114         if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) {
00115                 return (ISC_R_FAILURE);
00116         }
00117 #else
00118         isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
00119 
00120         isc_sha1_update(sha1ctx, data->base, data->length);
00121 #endif
00122         return (ISC_R_SUCCESS);
00123 }
00124 
00125 static int
00126 BN_bn2bin_fixed(BIGNUM *bn, unsigned char *buf, int size) {
00127         int bytes = size - BN_num_bytes(bn);
00128         while (bytes-- > 0)
00129                 *buf++ = 0;
00130         BN_bn2bin(bn, buf);
00131         return (size);
00132 }
00133 
00134 static isc_result_t
00135 openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
00136         dst_key_t *key = dctx->key;
00137         DSA *dsa = key->keydata.dsa;
00138         isc_region_t r;
00139         DSA_SIG *dsasig;
00140 #if USE_EVP
00141         EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
00142         EVP_PKEY *pkey;
00143         unsigned char *sigbuf;
00144         const unsigned char *sb;
00145         unsigned int siglen;
00146 #else
00147         isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
00148         unsigned char digest[ISC_SHA1_DIGESTLENGTH];
00149 #endif
00150 
00151         isc_buffer_availableregion(sig, &r);
00152         if (r.length < ISC_SHA1_DIGESTLENGTH * 2 + 1)
00153                 return (ISC_R_NOSPACE);
00154 
00155 #if USE_EVP
00156         pkey = EVP_PKEY_new();
00157         if (pkey == NULL)
00158                 return (ISC_R_NOMEMORY);
00159         if (!EVP_PKEY_set1_DSA(pkey, dsa)) {
00160                 EVP_PKEY_free(pkey);
00161                 return (ISC_R_FAILURE);
00162         }
00163         sigbuf = malloc(EVP_PKEY_size(pkey));
00164         if (sigbuf == NULL) {
00165                 EVP_PKEY_free(pkey);
00166                 return (ISC_R_NOMEMORY);
00167         }
00168         if (!EVP_SignFinal(evp_md_ctx, sigbuf, &siglen, pkey)) {
00169                 EVP_PKEY_free(pkey);
00170                 free(sigbuf);
00171                 return (dst__openssl_toresult3(dctx->category,
00172                                                "EVP_SignFinal",
00173                                                ISC_R_FAILURE));
00174         }
00175         INSIST(EVP_PKEY_size(pkey) >= (int) siglen);
00176         EVP_PKEY_free(pkey);
00177         
00178         dsasig = DSA_SIG_new();
00179         if (dsasig == NULL) {
00180                 free(sigbuf);
00181                 return (ISC_R_NOMEMORY);
00182         }
00183         sb = sigbuf;
00184         if (d2i_DSA_SIG(&dsasig, &sb, (long) siglen) == NULL) {
00185                 free(sigbuf);
00186                 return (dst__openssl_toresult3(dctx->category,
00187                                                "d2i_DSA_SIG",
00188                                                ISC_R_FAILURE));
00189         }
00190         free(sigbuf);
00191 #elif 0
00192         
00193         if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &siglen)) {
00194                 return (dst__openssl_toresult3(dctx->category,
00195                                                "EVP_DigestFinal_ex",
00196                                                ISC_R_FAILURE));
00197         }
00198         dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa);
00199         if (dsasig == NULL)
00200                 return (dst__openssl_toresult3(dctx->category,
00201                                                "DSA_do_sign",
00202                                                DST_R_SIGNFAILURE));
00203 #else
00204         isc_sha1_final(sha1ctx, digest);
00205 
00206         dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa);
00207         if (dsasig == NULL)
00208                 return (dst__openssl_toresult3(dctx->category,
00209                                                "DSA_do_sign",
00210                                                DST_R_SIGNFAILURE));
00211 #endif
00212         *r.base++ = (key->key_size - 512)/64;
00213         BN_bn2bin_fixed(dsasig->r, r.base, ISC_SHA1_DIGESTLENGTH);
00214         r.base += ISC_SHA1_DIGESTLENGTH;
00215         BN_bn2bin_fixed(dsasig->s, r.base, ISC_SHA1_DIGESTLENGTH);
00216         r.base += ISC_SHA1_DIGESTLENGTH;
00217         DSA_SIG_free(dsasig);
00218         isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH * 2 + 1);
00219 
00220         return (ISC_R_SUCCESS);
00221 }
00222 
00223 static isc_result_t
00224 openssldsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
00225         dst_key_t *key = dctx->key;
00226         DSA *dsa = key->keydata.dsa;
00227         int status = 0;
00228         unsigned char *cp = sig->base;
00229         DSA_SIG *dsasig;
00230 #if USE_EVP
00231         EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
00232 #if 0
00233         EVP_PKEY *pkey;
00234         unsigned char *sigbuf;
00235 #endif
00236         unsigned int siglen;
00237 #else
00238         isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
00239 #endif
00240         unsigned char digest[ISC_SHA1_DIGESTLENGTH];
00241 
00242 
00243 #if USE_EVP
00244 #if 1
00245         
00246         if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &siglen)) {
00247                 return (ISC_R_FAILURE);
00248         }
00249 #endif
00250 #else
00251         isc_sha1_final(sha1ctx, digest);
00252 #endif
00253 
00254         if (sig->length != 2 * ISC_SHA1_DIGESTLENGTH + 1) {
00255                 return (DST_R_VERIFYFAILURE);
00256         }
00257 
00258         cp++;   
00259         dsasig = DSA_SIG_new();
00260         if (dsasig == NULL)
00261                 return (ISC_R_NOMEMORY);
00262         dsasig->r = BN_bin2bn(cp, ISC_SHA1_DIGESTLENGTH, NULL);
00263         cp += ISC_SHA1_DIGESTLENGTH;
00264         dsasig->s = BN_bin2bn(cp, ISC_SHA1_DIGESTLENGTH, NULL);
00265 
00266 #if 0
00267         pkey = EVP_PKEY_new();
00268         if (pkey == NULL)
00269                 return (ISC_R_NOMEMORY);
00270         if (!EVP_PKEY_set1_DSA(pkey, dsa)) {
00271                 EVP_PKEY_free(pkey);
00272                 return (ISC_R_FAILURE);
00273         }
00274         
00275         sigbuf = malloc(EVP_PKEY_size(pkey) + 50);
00276         if (sigbuf == NULL) {
00277                 EVP_PKEY_free(pkey);
00278                 return (ISC_R_NOMEMORY);
00279         }
00280         siglen = (unsigned) i2d_DSA_SIG(dsasig, &sigbuf);
00281         INSIST(EVP_PKEY_size(pkey) >= (int) siglen);
00282         status = EVP_VerifyFinal(evp_md_ctx, sigbuf, siglen, pkey);
00283         EVP_PKEY_free(pkey);
00284         free(sigbuf);
00285 #else
00286         status = DSA_do_verify(digest, ISC_SHA1_DIGESTLENGTH, dsasig, dsa);
00287 #endif
00288         DSA_SIG_free(dsasig);
00289         switch (status) {
00290         case 1:
00291                 return (ISC_R_SUCCESS);
00292         case 0:
00293                 return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
00294         default:
00295                 return (dst__openssl_toresult3(dctx->category,
00296                                                "DSA_do_verify",
00297                                                DST_R_VERIFYFAILURE));
00298         }
00299 }
00300 
00301 static isc_boolean_t
00302 openssldsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
00303         int status;
00304         DSA *dsa1, *dsa2;
00305 
00306         dsa1 = key1->keydata.dsa;
00307         dsa2 = key2->keydata.dsa;
00308 
00309         if (dsa1 == NULL && dsa2 == NULL)
00310                 return (ISC_TRUE);
00311         else if (dsa1 == NULL || dsa2 == NULL)
00312                 return (ISC_FALSE);
00313 
00314         status = BN_cmp(dsa1->p, dsa2->p) ||
00315                  BN_cmp(dsa1->q, dsa2->q) ||
00316                  BN_cmp(dsa1->g, dsa2->g) ||
00317                  BN_cmp(dsa1->pub_key, dsa2->pub_key);
00318 
00319         if (status != 0)
00320                 return (ISC_FALSE);
00321 
00322         if (dsa1->priv_key != NULL || dsa2->priv_key != NULL) {
00323                 if (dsa1->priv_key == NULL || dsa2->priv_key == NULL)
00324                         return (ISC_FALSE);
00325                 if (BN_cmp(dsa1->priv_key, dsa2->priv_key))
00326                         return (ISC_FALSE);
00327         }
00328         return (ISC_TRUE);
00329 }
00330 
00331 #if OPENSSL_VERSION_NUMBER > 0x00908000L
00332 static int
00333 progress_cb(int p, int n, BN_GENCB *cb)
00334 {
00335         union {
00336                 void *dptr;
00337                 void (*fptr)(int);
00338         } u;
00339 
00340         UNUSED(n);
00341 
00342         u.dptr = cb->arg;
00343         if (u.fptr != NULL)
00344                 u.fptr(p);
00345         return (1);
00346 }
00347 #endif
00348 
00349 static isc_result_t
00350 openssldsa_generate(dst_key_t *key, int unused, void (*callback)(int)) {
00351         DSA *dsa;
00352         unsigned char rand_array[ISC_SHA1_DIGESTLENGTH];
00353         isc_result_t result;
00354 #if OPENSSL_VERSION_NUMBER > 0x00908000L
00355         BN_GENCB cb;
00356         union {
00357                 void *dptr;
00358                 void (*fptr)(int);
00359         } u;
00360 
00361 #else
00362 
00363         UNUSED(callback);
00364 #endif
00365         UNUSED(unused);
00366 
00367         result = dst__entropy_getdata(rand_array, sizeof(rand_array),
00368                                       ISC_FALSE);
00369         if (result != ISC_R_SUCCESS)
00370                 return (result);
00371 
00372 #if OPENSSL_VERSION_NUMBER > 0x00908000L
00373         dsa = DSA_new();
00374         if (dsa == NULL)
00375                 return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
00376 
00377         if (callback == NULL) {
00378                 BN_GENCB_set_old(&cb, NULL, NULL);
00379         } else {
00380                 u.fptr = callback;
00381                 BN_GENCB_set(&cb, &progress_cb, u.dptr);
00382         }
00383 
00384         if (!DSA_generate_parameters_ex(dsa, key->key_size, rand_array,
00385                                         ISC_SHA1_DIGESTLENGTH,  NULL, NULL,
00386                                         &cb))
00387         {
00388                 DSA_free(dsa);
00389                 return (dst__openssl_toresult2("DSA_generate_parameters_ex",
00390                                                DST_R_OPENSSLFAILURE));
00391         }
00392 #else
00393         dsa = DSA_generate_parameters(key->key_size, rand_array,
00394                                       ISC_SHA1_DIGESTLENGTH, NULL, NULL,
00395                                       NULL, NULL);
00396         if (dsa == NULL)
00397                 return (dst__openssl_toresult2("DSA_generate_parameters",
00398                                                DST_R_OPENSSLFAILURE));
00399 #endif
00400 
00401         if (DSA_generate_key(dsa) == 0) {
00402                 DSA_free(dsa);
00403                 return (dst__openssl_toresult2("DSA_generate_key",
00404                                                DST_R_OPENSSLFAILURE));
00405         }
00406         dsa->flags &= ~DSA_FLAG_CACHE_MONT_P;
00407 
00408         key->keydata.dsa = dsa;
00409 
00410         return (ISC_R_SUCCESS);
00411 }
00412 
00413 static isc_boolean_t
00414 openssldsa_isprivate(const dst_key_t *key) {
00415         DSA *dsa = key->keydata.dsa;
00416         return (ISC_TF(dsa != NULL && dsa->priv_key != NULL));
00417 }
00418 
00419 static void
00420 openssldsa_destroy(dst_key_t *key) {
00421         DSA *dsa = key->keydata.dsa;
00422         DSA_free(dsa);
00423         key->keydata.dsa = NULL;
00424 }
00425 
00426 
00427 static isc_result_t
00428 openssldsa_todns(const dst_key_t *key, isc_buffer_t *data) {
00429         DSA *dsa;
00430         isc_region_t r;
00431         int dnslen;
00432         unsigned int t, p_bytes;
00433 
00434         REQUIRE(key->keydata.dsa != NULL);
00435 
00436         dsa = key->keydata.dsa;
00437 
00438         isc_buffer_availableregion(data, &r);
00439 
00440         t = (BN_num_bytes(dsa->p) - 64) / 8;
00441         if (t > 8)
00442                 return (DST_R_INVALIDPUBLICKEY);
00443         p_bytes = 64 + 8 * t;
00444 
00445         dnslen = 1 + (key->key_size * 3)/8 + ISC_SHA1_DIGESTLENGTH;
00446         if (r.length < (unsigned int) dnslen)
00447                 return (ISC_R_NOSPACE);
00448 
00449         *r.base++ = t;
00450         BN_bn2bin_fixed(dsa->q, r.base, ISC_SHA1_DIGESTLENGTH);
00451         r.base += ISC_SHA1_DIGESTLENGTH;
00452         BN_bn2bin_fixed(dsa->p, r.base, key->key_size/8);
00453         r.base += p_bytes;
00454         BN_bn2bin_fixed(dsa->g, r.base, key->key_size/8);
00455         r.base += p_bytes;
00456         BN_bn2bin_fixed(dsa->pub_key, r.base, key->key_size/8);
00457         r.base += p_bytes;
00458 
00459         isc_buffer_add(data, dnslen);
00460 
00461         return (ISC_R_SUCCESS);
00462 }
00463 
00464 static isc_result_t
00465 openssldsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
00466         DSA *dsa;
00467         isc_region_t r;
00468         unsigned int t, p_bytes;
00469         isc_mem_t *mctx = key->mctx;
00470 
00471         UNUSED(mctx);
00472 
00473         isc_buffer_remainingregion(data, &r);
00474         if (r.length == 0)
00475                 return (ISC_R_SUCCESS);
00476 
00477         dsa = DSA_new();
00478         if (dsa == NULL)
00479                 return (ISC_R_NOMEMORY);
00480         dsa->flags &= ~DSA_FLAG_CACHE_MONT_P;
00481 
00482         t = (unsigned int) *r.base++;
00483         if (t > 8) {
00484                 DSA_free(dsa);
00485                 return (DST_R_INVALIDPUBLICKEY);
00486         }
00487         p_bytes = 64 + 8 * t;
00488 
00489         if (r.length < 1 + ISC_SHA1_DIGESTLENGTH + 3 * p_bytes) {
00490                 DSA_free(dsa);
00491                 return (DST_R_INVALIDPUBLICKEY);
00492         }
00493 
00494         dsa->q = BN_bin2bn(r.base, ISC_SHA1_DIGESTLENGTH, NULL);
00495         r.base += ISC_SHA1_DIGESTLENGTH;
00496 
00497         dsa->p = BN_bin2bn(r.base, p_bytes, NULL);
00498         r.base += p_bytes;
00499 
00500         dsa->g = BN_bin2bn(r.base, p_bytes, NULL);
00501         r.base += p_bytes;
00502 
00503         dsa->pub_key = BN_bin2bn(r.base, p_bytes, NULL);
00504         r.base += p_bytes;
00505 
00506         key->key_size = p_bytes * 8;
00507 
00508         isc_buffer_forward(data, 1 + ISC_SHA1_DIGESTLENGTH + 3 * p_bytes);
00509 
00510         key->keydata.dsa = dsa;
00511 
00512         return (ISC_R_SUCCESS);
00513 }
00514 
00515 
00516 static isc_result_t
00517 openssldsa_tofile(const dst_key_t *key, const char *directory) {
00518         int cnt = 0;
00519         DSA *dsa;
00520         dst_private_t priv;
00521         unsigned char bufs[5][128];
00522 
00523         if (key->keydata.dsa == NULL)
00524                 return (DST_R_NULLKEY);
00525 
00526         if (key->external) {
00527                 priv.nelements = 0;
00528                 return (dst__privstruct_writefile(key, &priv, directory));
00529         }
00530 
00531         dsa = key->keydata.dsa;
00532 
00533         priv.elements[cnt].tag = TAG_DSA_PRIME;
00534         priv.elements[cnt].length = BN_num_bytes(dsa->p);
00535         BN_bn2bin(dsa->p, bufs[cnt]);
00536         priv.elements[cnt].data = bufs[cnt];
00537         cnt++;
00538 
00539         priv.elements[cnt].tag = TAG_DSA_SUBPRIME;
00540         priv.elements[cnt].length = BN_num_bytes(dsa->q);
00541         BN_bn2bin(dsa->q, bufs[cnt]);
00542         priv.elements[cnt].data = bufs[cnt];
00543         cnt++;
00544 
00545         priv.elements[cnt].tag = TAG_DSA_BASE;
00546         priv.elements[cnt].length = BN_num_bytes(dsa->g);
00547         BN_bn2bin(dsa->g, bufs[cnt]);
00548         priv.elements[cnt].data = bufs[cnt];
00549         cnt++;
00550 
00551         priv.elements[cnt].tag = TAG_DSA_PRIVATE;
00552         priv.elements[cnt].length = BN_num_bytes(dsa->priv_key);
00553         BN_bn2bin(dsa->priv_key, bufs[cnt]);
00554         priv.elements[cnt].data = bufs[cnt];
00555         cnt++;
00556 
00557         priv.elements[cnt].tag = TAG_DSA_PUBLIC;
00558         priv.elements[cnt].length = BN_num_bytes(dsa->pub_key);
00559         BN_bn2bin(dsa->pub_key, bufs[cnt]);
00560         priv.elements[cnt].data = bufs[cnt];
00561         cnt++;
00562 
00563         priv.nelements = cnt;
00564         return (dst__privstruct_writefile(key, &priv, directory));
00565 }
00566 
00567 static isc_result_t
00568 openssldsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
00569         dst_private_t priv;
00570         isc_result_t ret;
00571         int i;
00572         DSA *dsa = NULL;
00573         isc_mem_t *mctx = key->mctx;
00574 #define DST_RET(a) {ret = a; goto err;}
00575 
00576         
00577         ret = dst__privstruct_parse(key, DST_ALG_DSA, lexer, mctx, &priv);
00578         if (ret != ISC_R_SUCCESS)
00579                 return (ret);
00580 
00581         if (key->external) {
00582                 if (priv.nelements != 0)
00583                         DST_RET(DST_R_INVALIDPRIVATEKEY);
00584                 if (pub == NULL)
00585                         DST_RET(DST_R_INVALIDPRIVATEKEY);
00586                 key->keydata.pkey = pub->keydata.pkey;
00587                 pub->keydata.pkey = NULL;
00588                 key->key_size = pub->key_size;
00589                 dst__privstruct_free(&priv, mctx);
00590                 memset(&priv, 0, sizeof(priv));
00591                 return (ISC_R_SUCCESS);
00592         }
00593 
00594         dsa = DSA_new();
00595         if (dsa == NULL)
00596                 DST_RET(ISC_R_NOMEMORY);
00597         dsa->flags &= ~DSA_FLAG_CACHE_MONT_P;
00598         key->keydata.dsa = dsa;
00599 
00600         for (i = 0; i < priv.nelements; i++) {
00601                 BIGNUM *bn;
00602                 bn = BN_bin2bn(priv.elements[i].data,
00603                                priv.elements[i].length, NULL);
00604                 if (bn == NULL)
00605                         DST_RET(ISC_R_NOMEMORY);
00606 
00607                 switch (priv.elements[i].tag) {
00608                         case TAG_DSA_PRIME:
00609                                 dsa->p = bn;
00610                                 break;
00611                         case TAG_DSA_SUBPRIME:
00612                                 dsa->q = bn;
00613                                 break;
00614                         case TAG_DSA_BASE:
00615                                 dsa->g = bn;
00616                                 break;
00617                         case TAG_DSA_PRIVATE:
00618                                 dsa->priv_key = bn;
00619                                 break;
00620                         case TAG_DSA_PUBLIC:
00621                                 dsa->pub_key = bn;
00622                                 break;
00623                 }
00624         }
00625         dst__privstruct_free(&priv, mctx);
00626         memset(&priv, 0, sizeof(priv));
00627         key->key_size = BN_num_bits(dsa->p);
00628         return (ISC_R_SUCCESS);
00629 
00630  err:
00631         openssldsa_destroy(key);
00632         dst__privstruct_free(&priv, mctx);
00633         memset(&priv, 0, sizeof(priv));
00634         return (ret);
00635 }
00636 
00637 static dst_func_t openssldsa_functions = {
00638         openssldsa_createctx,
00639         NULL, 
00640         openssldsa_destroyctx,
00641         openssldsa_adddata,
00642         openssldsa_sign,
00643         openssldsa_verify,
00644         NULL, 
00645         NULL, 
00646         openssldsa_compare,
00647         NULL, 
00648         openssldsa_generate,
00649         openssldsa_isprivate,
00650         openssldsa_destroy,
00651         openssldsa_todns,
00652         openssldsa_fromdns,
00653         openssldsa_tofile,
00654         openssldsa_parse,
00655         NULL, 
00656         NULL, 
00657         NULL, 
00658         NULL, 
00659 };
00660 
00661 isc_result_t
00662 dst__openssldsa_init(dst_func_t **funcp) {
00663         REQUIRE(funcp != NULL);
00664         if (*funcp == NULL)
00665                 *funcp = &openssldsa_functions;
00666         return (ISC_R_SUCCESS);
00667 }
00668 
00669 #else 
00670 
00671 #include <isc/util.h>
00672 
00673 EMPTY_TRANSLATION_UNIT
00674 
00675 #endif 
00676