]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3354. [func] Improve OpenSSL error logging. [RT #29932]
authorMark Andrews <marka@isc.org>
Mon, 23 Jul 2012 06:30:55 +0000 (16:30 +1000)
committerMark Andrews <marka@isc.org>
Mon, 23 Jul 2012 06:30:55 +0000 (16:30 +1000)
CHANGES
bin/tests/dst/t_dst.c
lib/dns/dst_openssl.h
lib/dns/dst_result.c
lib/dns/include/dns/log.h
lib/dns/include/dst/result.h
lib/dns/log.c
lib/dns/openssl_link.c
lib/dns/openssldh_link.c
lib/dns/openssldsa_link.c
lib/dns/opensslrsa_link.c

diff --git a/CHANGES b/CHANGES
index 584b2c931350362b555971b3466007104f83d3df..f0ac0537de1fa89be3b67ed05a8e77ab8be5f7dd 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,5 @@
+3354.  [func]          Improve OpenSSL error logging. [RT #29932]
+
 3352.  [bug]           Ensure that learned server attributes timeout of the
                        adb cache. [RT #29856]
 
index 3abcd450fb80a0dc07838717657946c8ceb4d495..91f38638ff4adc9e166d9fc4efc5d5847de9eb1e 100644 (file)
@@ -179,7 +179,7 @@ dh(dns_name_t *name1, int id1, dns_name_t *name2, int id2, isc_mem_t *mctx,
        if (p == NULL) {
                t_info("getcwd failed %d\n", errno);
                ++*nprobs;
-               return;
+               goto cleanup;
        }
 
        ret = dst_key_fromfile(name1, id1, alg, type, current, mctx, &key1);
@@ -187,7 +187,7 @@ dh(dns_name_t *name1, int id1, dns_name_t *name2, int id2, isc_mem_t *mctx,
                t_info("dst_key_fromfile(%d) returned: %s\n",
                       alg, dst_result_totext(ret));
                ++*nfails;
-               return;
+               goto cleanup;
        }
 
        ret = dst_key_fromfile(name2, id2, alg, type, current, mctx, &key2);
@@ -195,7 +195,7 @@ dh(dns_name_t *name1, int id1, dns_name_t *name2, int id2, isc_mem_t *mctx,
                t_info("dst_key_fromfile(%d) returned: %s\n",
                       alg, dst_result_totext(ret));
                ++*nfails;
-               return;
+               goto cleanup;
        }
 
        ret = isc_file_mktemplate("/tmp/", tmp, sizeof(tmp));
@@ -203,7 +203,7 @@ dh(dns_name_t *name1, int id1, dns_name_t *name2, int id2, isc_mem_t *mctx,
                t_info("isc_file_mktemplate failed %s\n",
                       isc_result_totext(ret));
                ++*nprobs;
-               return;
+               goto cleanup;
        }
 
        ret = isc_dir_createunique(tmp);
@@ -211,7 +211,7 @@ dh(dns_name_t *name1, int id1, dns_name_t *name2, int id2, isc_mem_t *mctx,
                t_info("isc_dir_createunique failed %s\n",
                       isc_result_totext(ret));
                ++*nprobs;
-               return;
+               goto cleanup;
        }
 
        ret = dst_key_tofile(key1, type, tmp);
@@ -219,7 +219,7 @@ dh(dns_name_t *name1, int id1, dns_name_t *name2, int id2, isc_mem_t *mctx,
                t_info("dst_key_tofile(%d) returned: %s\n",
                       alg, dst_result_totext(ret));
                ++*nfails;
-               return;
+               goto cleanup;
        }
 
        ret = dst_key_tofile(key2, type, tmp);
@@ -227,7 +227,7 @@ dh(dns_name_t *name1, int id1, dns_name_t *name2, int id2, isc_mem_t *mctx,
                t_info("dst_key_tofile(%d) returned: %s\n",
                       alg, dst_result_totext(ret));
                ++*nfails;
-               return;
+               goto cleanup;
        }
 
        cleandir(tmp);
@@ -238,7 +238,7 @@ dh(dns_name_t *name1, int id1, dns_name_t *name2, int id2, isc_mem_t *mctx,
                t_info("dst_computesecret() returned: %s\n",
                       dst_result_totext(ret));
                ++*nfails;
-               return;
+               goto cleanup;
        }
 
        isc_buffer_init(&b2, array2, sizeof(array2));
@@ -247,7 +247,7 @@ dh(dns_name_t *name1, int id1, dns_name_t *name2, int id2, isc_mem_t *mctx,
                t_info("dst_computesecret() returned: %s\n",
                       dst_result_totext(ret));
                ++*nfails;
-               return;
+               goto cleanup;
        }
 
        isc_buffer_usedregion(&b1, &r1);
@@ -256,11 +256,14 @@ dh(dns_name_t *name1, int id1, dns_name_t *name2, int id2, isc_mem_t *mctx,
        {
                t_info("computed secrets don't match\n");
                ++*nfails;
-               return;
+               goto cleanup;
        }
 
-       dst_key_free(&key1);
-       dst_key_free(&key2);
+ cleanup:
+       if (key1 != NULL)
+               dst_key_free(&key1);
+       if (key2 != NULL)
+               dst_key_free(&key2);
 }
 
 static void
@@ -330,12 +333,14 @@ generate(int alg, isc_mem_t *mctx, int size, int *nfails) {
                t_info("dst_key_generate(%d) returned: %s\n", alg,
                       dst_result_totext(ret));
                ++*nfails;
-               return;
+               goto cleanup;
        }
 
        if (alg != DST_ALG_DH)
                use(key, mctx, ISC_R_SUCCESS, nfails);
-       dst_key_free(&key);
+ cleanup:
+       if (key != NULL)
+               dst_key_free(&key);
 }
 
 #define        DBUFSIZ 25
@@ -787,14 +792,20 @@ t2_sigchk(char *datapath, char *sigpath, char *keyname,
        if (isc_result != ISC_R_SUCCESS) {
                t_info("dst_context_create returned %s\n",
                        isc_result_totext(isc_result));
+               (void) free(data);
+               dst_key_free(&key);
                ++*nfails;
+               return;
        }
        isc_result = dst_context_adddata(ctx, &datareg);
        if (isc_result != ISC_R_SUCCESS) {
                t_info("dst_context_adddata returned %s\n",
                        isc_result_totext(isc_result));
+               (void) free(data);
                dst_context_destroy(&ctx);
+               dst_key_free(&key);
                ++*nfails;
+               return;
        }
        isc_result = dst_context_verify(ctx, &sigreg);
        if (    ((exp_res == 0) && (isc_result != ISC_R_SUCCESS))       ||
@@ -803,7 +814,6 @@ t2_sigchk(char *datapath, char *sigpath, char *keyname,
                t_info("dst_context_verify returned %s, expected %s\n",
                        isc_result_totext(isc_result),
                        expected_result);
-               dst_context_destroy(&ctx);
                ++*nfails;
        }
 
index 287c1a47d99af5a049cd8f872f95c09410c69c65..4ecbb22ac195018b8a579753ebeb22f10076cea7 100644 (file)
@@ -39,6 +39,9 @@ ISC_LANG_BEGINDECLS
 isc_result_t
 dst__openssl_toresult(isc_result_t fallback);
 
+isc_result_t
+dst__openssl_toresult2(const char *funcname, isc_result_t fallback);
+
 #ifdef USE_ENGINE
 ENGINE *
 dst__openssl_getengine(const char *engine);
index 429dbb2fc1cf81e7193bbf5529fdd910d1e28bfe..d5ee38d16930758f625a8a71f8997ab43404b454 100644 (file)
@@ -30,7 +30,7 @@
 
 static const char *text[DST_R_NRESULTS] = {
        "algorithm is unsupported",             /*%< 0 */
-       "openssl failure",                      /*%< 1 */
+       "crypto failure",                       /*%< 1 */
        "built with no crypto support",         /*%< 2 */
        "illegal operation for a null key",     /*%< 3 */
        "public key is invalid",                /*%< 4 */
index 6c874301f252b679c7ab7fafa55e83942589a72c..fbcd2def8986464e594bc9080899dd154c01f781 100644 (file)
@@ -74,6 +74,7 @@ LIBDNS_EXTERNAL_DATA extern isc_logmodule_t dns_modules[];
 #define DNS_LOGMODULE_ACACHE           (&dns_modules[25])
 #define DNS_LOGMODULE_DLZ              (&dns_modules[26])
 #define DNS_LOGMODULE_DNSSEC           (&dns_modules[27])
+#define DNS_LOGMODULE_CRYPTO           (&dns_modules[28])
 
 ISC_LANG_BEGINDECLS
 
index d77b72e77a6e5d12c677ba23d802995c3178aeb2..9b6389d11d72d3d1e8265bc8c81cd993356a2147 100644 (file)
@@ -34,7 +34,9 @@
 #include <isc/result.h>                /* Contractual promise. */
 
 #define DST_R_UNSUPPORTEDALG           (ISC_RESULTCLASS_DST + 0)
-#define DST_R_OPENSSLFAILURE           (ISC_RESULTCLASS_DST + 1)
+#define DST_R_CRYPTOFAILURE            (ISC_RESULTCLASS_DST + 1)
+/* compat */
+#define DST_R_OPENSSLFAILURE           DST_R_CRYPTOFAILURE
 #define DST_R_NOCRYPTO                 (ISC_RESULTCLASS_DST + 2)
 #define DST_R_NULLKEY                  (ISC_RESULTCLASS_DST + 3)
 #define DST_R_INVALIDPUBLICKEY         (ISC_RESULTCLASS_DST + 4)
index b49e6505bccf0c4da909652d934a2f4879a24366..3c9727df72c1212be516751657a5b23e6d20a170 100644 (file)
@@ -80,6 +80,7 @@ LIBDNS_EXTERNAL_DATA isc_logmodule_t dns_modules[] = {
        { "dns/acache",         0 },
        { "dns/dlz",            0 },
        { "dns/dnssec",         0 },
+       { "dns/crypto",         0 },
        { NULL,                 0 }
 };
 
index 83dd1fc666d3454a8b8072da93e7290f45809cf0..9ac78f2e64663f7337f9a8135e65194ce16b1768 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Portions Copyright (C) 2004-2012  Internet Systems Consortium, Inc. ("ISC")
+ * Poetions Copyright (C) 2004-2012  Internet Systems Consortnum, Inc. ("ISC")
  * Portions Copyright (C) 1999-2003  Internet Software Consortium.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
 #include <isc/thread.h>
 #include <isc/util.h>
 
+#include <dns/log.h>
+
+#include <dst/result.h>
+
 #include "dst_internal.h"
 #include "dst_openssl.h"
 
@@ -166,6 +170,8 @@ dst__openssl_init() {
        CRYPTO_set_locking_callback(lock_callback);
        CRYPTO_set_id_callback(id_callback);
 
+       ERR_load_crypto_strings();
+
        rm = mem_alloc(sizeof(RAND_METHOD));
        if (rm == NULL) {
                result = ISC_R_NOMEMORY;
@@ -317,7 +323,7 @@ dst__openssl_destroy() {
 isc_result_t
 dst__openssl_toresult(isc_result_t fallback) {
        isc_result_t result = fallback;
-       int err = ERR_get_error();
+       unsigned long err = ERR_get_error();
 
        switch (ERR_GET_REASON(err)) {
        case ERR_R_MALLOC_FAILURE:
@@ -330,6 +336,40 @@ dst__openssl_toresult(isc_result_t fallback) {
        return (result);
 }
 
+isc_result_t
+dst__openssl_toresult2(const char *funcname, isc_result_t fallback) {
+       isc_result_t result = fallback;
+       unsigned long err = ERR_peek_error();
+       const char *file, *data;
+       int line, flags;
+       char buf[256];
+
+       switch (ERR_GET_REASON(err)) {
+       case ERR_R_MALLOC_FAILURE:
+               result = ISC_R_NOMEMORY;
+               goto done;
+       default:
+               break;
+       }
+       isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
+                     DNS_LOGMODULE_CRYPTO, ISC_LOG_WARNING,
+                     "%s failed", funcname);
+       for (;;) {
+               err = ERR_get_error_line_data(&file, &line, &data, &flags);
+               if (err == 0)
+                       goto done;
+               ERR_error_string_n(err, buf, sizeof(buf));
+               isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
+                             DNS_LOGMODULE_CRYPTO, ISC_LOG_INFO,
+                             "%s:%s:%d:%s", buf, file, line,
+                             (flags & ERR_TXT_STRING) ? data : "");
+       }
+
+    done:
+       ERR_clear_error();
+       return (result);
+}
+
 #if defined(USE_ENGINE)
 ENGINE *
 dst__openssl_getengine(const char *name) {
index be1d880280eb4b1109aa3c87cae513089333d13b..04fb9fe5afa1313e2df9eb3462402f74aff0d4c6 100644 (file)
@@ -94,7 +94,8 @@ openssldh_computesecret(const dst_key_t *pub, const dst_key_t *priv,
                return (ISC_R_NOSPACE);
        ret = DH_compute_key(r.base, dhpub->pub_key, dhpriv);
        if (ret == 0)
-               return (dst__openssl_toresult(DST_R_COMPUTESECRETFAILURE));
+               return (dst__openssl_toresult2("DH_compute_key",
+                                              DST_R_COMPUTESECRETFAILURE));
        isc_buffer_add(secret, len);
        return (ISC_R_SUCCESS);
 }
@@ -179,14 +180,16 @@ openssldh_generate(dst_key_t *key, int generator) {
 #if OPENSSL_VERSION_NUMBER > 0x00908000L
                dh = DH_new();
                if (dh == NULL)
-                       return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+                       return (dst__openssl_toresult(ISC_R_NOMEMORY));
 
                BN_GENCB_set_old(&cb, NULL, NULL);
 
                if (!DH_generate_parameters_ex(dh, key->key_size, generator,
                                               &cb)) {
                        DH_free(dh);
-                       return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+                       return (dst__openssl_toresult2(
+                                       "DH_generate_parameters_ex",
+                                       DST_R_OPENSSLFAILURE));
                }
 #else
                dh = DH_generate_parameters(key->key_size, generator,
@@ -195,11 +198,13 @@ openssldh_generate(dst_key_t *key, int generator) {
        }
 
        if (dh == NULL)
-               return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+               return (dst__openssl_toresult2("DH_generate_parameters",
+                                              DST_R_OPENSSLFAILURE));
 
        if (DH_generate_key(dh) == 0) {
                DH_free(dh);
-               return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+               return (dst__openssl_toresult2("DH_generate_key",
+                                              DST_R_OPENSSLFAILURE));
        }
        dh->flags &= ~DH_FLAG_CACHE_MONT_P;
 
@@ -430,6 +435,7 @@ openssldh_tofile(const dst_key_t *key, const char *directory) {
 
        dh = key->keydata.dh;
 
+       memset(bufs, 0, sizeof(bufs));
        for (i = 0; i < 4; i++) {
                bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(dh->p));
                if (bufs[i] == NULL) {
index c93c119959cd13802b7afbfe8ff7084306b322b7..68d19745e4192126046f59bc1008c6b81779c46e 100644 (file)
@@ -168,7 +168,8 @@ openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
        if (!EVP_SignFinal(evp_md_ctx, sigbuf, &siglen, pkey)) {
                EVP_PKEY_free(pkey);
                free(sigbuf);
-               return (ISC_R_FAILURE);
+               return (dst__openssl_toresult2("EVP_SignFinal",
+                                              ISC_R_FAILURE));
        }
        INSIST(EVP_PKEY_size(pkey) >= (int) siglen);
        EVP_PKEY_free(pkey);
@@ -181,23 +182,26 @@ openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
        sb = sigbuf;
        if (d2i_DSA_SIG(&dsasig, &sb, (long) siglen) == NULL) {
                free(sigbuf);
-               return (ISC_R_FAILURE);
+               return (dst__openssl_toresult2("d2i_DSA_SIG", ISC_R_FAILURE));
        }
        free(sigbuf);
 #elif 0
        /* Only use EVP for the Digest */
        if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &siglen)) {
-               return (ISC_R_FAILURE);
+               return (dst__openssl_toresult2("EVP_DigestFinal_ex",
+                                              ISC_R_FAILURE));
        }
        dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa);
        if (dsasig == NULL)
-               return (dst__openssl_toresult(DST_R_SIGNFAILURE));
+               return (dst__openssl_toresult2("DSA_do_sign",
+                                              DST_R_SIGNFAILURE));
 #else
        isc_sha1_final(sha1ctx, digest);
 
        dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa);
        if (dsasig == NULL)
-               return (dst__openssl_toresult(DST_R_SIGNFAILURE));
+               return (dst__openssl_toresult2("DSA_do_sign",
+                                              DST_R_SIGNFAILURE));
 #endif
        *r.base++ = (key->key_size - 512)/64;
        BN_bn2bin_fixed(dsasig->r, r.base, ISC_SHA1_DIGESTLENGTH);
@@ -276,10 +280,15 @@ openssldsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
        status = DSA_do_verify(digest, ISC_SHA1_DIGESTLENGTH, dsasig, dsa);
 #endif
        DSA_SIG_free(dsasig);
-       if (status != 1)
+       switch (status) {
+       case 1:
+               return (ISC_R_SUCCESS);
+       case 0:
                return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
-
-       return (ISC_R_SUCCESS);
+       default:
+               return (dst__openssl_toresult2("DSA_do_verify",
+                                              DST_R_VERIFYFAILURE));
+       }
 }
 
 static isc_boolean_t
@@ -340,19 +349,22 @@ openssldsa_generate(dst_key_t *key, int unused) {
                                        &cb))
        {
                DSA_free(dsa);
-               return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+               return (dst__openssl_toresult2("DSA_generate_parameters_ex",
+                                              DST_R_OPENSSLFAILURE));
        }
 #else
        dsa = DSA_generate_parameters(key->key_size, rand_array,
                                      ISC_SHA1_DIGESTLENGTH, NULL, NULL,
                                      NULL, NULL);
        if (dsa == NULL)
-               return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+               return (dst__openssl_toresult2("DSA_generate_parameters",
+                                              DST_R_OPENSSLFAILURE));
 #endif
 
        if (DSA_generate_key(dsa) == 0) {
                DSA_free(dsa);
-               return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+               return (dst__openssl_toresult2("DSA_generate_key",
+                                              DST_R_OPENSSLFAILURE));
        }
        dsa->flags &= ~DSA_FLAG_CACHE_MONT_P;
 
index 02923978fddc98fa7924cf4783e149eea4ee1091..d9501fd28fdd68d8415209aa58d787a2e861228c 100644 (file)
@@ -155,7 +155,8 @@ opensslrsa_createctx(dst_key_t *key, dst_context_t *dctx) {
 
        if (!EVP_DigestInit_ex(evp_md_ctx, type, NULL)) {
                EVP_MD_CTX_destroy(evp_md_ctx);
-               return (ISC_R_FAILURE);
+               return (dst__openssl_toresult2("EVP_DigestInit_ex",
+                                              ISC_R_FAILURE));
        }
        dctx->ctxdata.evp_md_ctx = evp_md_ctx;
 #else
@@ -303,7 +304,8 @@ opensslrsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
 
 #if USE_EVP
        if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) {
-               return (ISC_R_FAILURE);
+               return (dst__openssl_toresult2("EVP_DigestUpdate",
+                                              ISC_R_FAILURE));
        }
 #else
        switch (dctx->key->key_alg) {
@@ -373,7 +375,6 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
        int status = 0;
        int type = 0;
        unsigned int digestlen = 0;
-       char *message;
        unsigned long err;
        const char* file;
        int line;
@@ -396,7 +397,8 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
                return (ISC_R_NOSPACE);
 
        if (!EVP_SignFinal(evp_md_ctx, r.base, &siglen, pkey)) {
-               return (ISC_R_FAILURE);
+               return (dst__openssl_toresult2("EVP_SignFinal",
+                                              ISC_R_FAILURE));
        }
 #else
        if (r.length < (unsigned int) RSA_size(rsa))
@@ -488,13 +490,9 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
        INSIST(type != 0);
        status = RSA_sign(type, digest, digestlen, r.base, &siglen, rsa);
 #endif
-       if (status == 0) {
-               err = ERR_peek_error_line(&file, &line);
-               if (err != 0U) {
-                       message = ERR_error_string(err, NULL);
-               }
-               return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
-       }
+       if (status == 0)
+               return (dst__openssl_toresult2("RSA_sign",
+                                              DST_R_OPENSSLFAILURE));
 #endif
 
        isc_buffer_add(sig, siglen);
@@ -614,7 +612,9 @@ opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
                                                    original, rsa,
                                                    RSA_PKCS1_PADDING);
                        if (status <= 0)
-                               return (DST_R_VERIFYFAILURE);
+                               return (dst__openssl_toresult2(
+                                               "RSA_public_decrypt",
+                                               DST_R_VERIFYFAILURE));
                        if (status != (int)(prefixlen + digestlen))
                                return (DST_R_VERIFYFAILURE);
                        if (memcmp(original, prefix, prefixlen))
@@ -635,7 +635,8 @@ opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
 #endif
 #endif
        if (status != 1)
-               return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
+               return (dst__openssl_toresult2("RSA_verify",
+                                              DST_R_VERIFYFAILURE));
 
        return (ISC_R_SUCCESS);
 }
@@ -708,6 +709,7 @@ opensslrsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
 static isc_result_t
 opensslrsa_generate(dst_key_t *key, int exp) {
 #if OPENSSL_VERSION_NUMBER > 0x00908000L
+       isc_result_t ret = DST_R_OPENSSLFAILURE;
        BN_GENCB cb;
        RSA *rsa = RSA_new();
        BIGNUM *e = BN_new();
@@ -748,6 +750,8 @@ opensslrsa_generate(dst_key_t *key, int exp) {
 #endif
                return (ISC_R_SUCCESS);
        }
+       ret = dst__openssl_toresult2("RSA_generate_key_ex",
+                                    DST_R_OPENSSLFAILURE);
 
 err:
 #if USE_EVP
@@ -758,7 +762,7 @@ err:
                BN_free(e);
        if (rsa != NULL)
                RSA_free(rsa);
-       return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+       return (dst__openssl_toresult(ret));
 #else
        RSA *rsa;
        unsigned long e;
@@ -778,7 +782,8 @@ err:
 #if USE_EVP
                EVP_PKEY_free(pkey);
 #endif
-               return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+               return (dst__openssl_toresult2("RSA_generate_key",
+                                              DST_R_OPENSSLFAILURE));
        }
        SET_FLAGS(rsa);
 #if USE_EVP
@@ -977,6 +982,7 @@ opensslrsa_tofile(const dst_key_t *key, const char *directory) {
        rsa = key->keydata.rsa;
 #endif
 
+       memset(bufs, 0, sizeof(bufs));
        for (i = 0; i < 8; i++) {
                bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(rsa->n));
                if (bufs[i] == NULL) {
@@ -1093,7 +1099,7 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer) {
        /* read private key file */
        ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv);
        if (ret != ISC_R_SUCCESS)
-               return (ret);
+               goto err;
 
        for (i = 0; i < priv.nelements; i++) {
                switch (priv.elements[i].tag) {
@@ -1119,10 +1125,10 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer) {
                if (e == NULL)
                        DST_RET(DST_R_NOENGINE);
                pkey = ENGINE_load_private_key(e, label, NULL, NULL);
-               if (pkey == NULL) {
-                       /* ERR_print_errors_fp(stderr); */
-                       DST_RET(ISC_R_NOTFOUND);
-               }
+               if (pkey == NULL)
+                       DST_RET(dst__openssl_toresult2(
+                                       "ENGINE_load_private_key",
+                                       ISC_R_NOTFOUND));
                key->engine = isc_mem_strdup(key->mctx, name);
                if (key->engine == NULL)
                        DST_RET(ISC_R_NOMEMORY);
@@ -1243,7 +1249,8 @@ opensslrsa_fromlabel(dst_key_t *key, const char *engine, const char *label,
                DST_RET(DST_R_NOENGINE);
        pkey = ENGINE_load_private_key(e, label, NULL, NULL);
        if (pkey == NULL)
-               DST_RET(ISC_R_NOTFOUND);
+               DST_RET(dst__openssl_toresult2("ENGINE_load_private_key",
+                                              ISC_R_NOTFOUND));
        key->engine = isc_mem_strdup(key->mctx, label);
        if (key->engine == NULL)
                DST_RET(ISC_R_NOMEMORY);