From 6eb6af6732194157224e2b8d81a02a9e80c4530a Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Mon, 23 Jul 2012 15:08:21 +1000 Subject: [PATCH] 3354. [func] Improve OpenSSL error logging. [RT #29932] --- CHANGES | 2 + bin/tests/dst/t_dst.c | 40 +++++++++++------- bin/tests/system/cleanpkcs11.sh | 2 +- bin/tests/system/conf.sh.in | 6 +-- lib/dns/ds.c | 4 +- lib/dns/dst_openssl.h | 3 ++ lib/dns/dst_result.c | 2 +- lib/dns/include/dns/log.h | 1 + lib/dns/include/dst/result.h | 4 +- lib/dns/log.c | 1 + lib/dns/openssl_link.c | 40 +++++++++++++++++- lib/dns/openssldh_link.c | 16 +++++--- lib/dns/openssldsa_link.c | 34 ++++++++++----- lib/dns/opensslecdsa_link.c | 50 ++++++++++++++-------- lib/dns/opensslgost_link.c | 73 ++++++++++++++++++++++----------- lib/dns/opensslrsa_link.c | 49 ++++++++++++---------- 16 files changed, 225 insertions(+), 102 deletions(-) diff --git a/CHANGES b/CHANGES index d7ac8e7d5b..872b3e30c6 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,5 @@ +3354. [func] Improve OpenSSL error logging. [RT #29932] + 3353. [bug] Use a single task for task exclusive operations. [RT #29872] diff --git a/bin/tests/dst/t_dst.c b/bin/tests/dst/t_dst.c index 5902ca9fe4..7642335e9c 100644 --- a/bin/tests/dst/t_dst.c +++ b/bin/tests/dst/t_dst.c @@ -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 @@ -382,12 +385,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 @@ -839,14 +844,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)) || @@ -855,7 +866,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; } diff --git a/bin/tests/system/cleanpkcs11.sh b/bin/tests/system/cleanpkcs11.sh index 3fee1c519d..e1cbc6fb58 100644 --- a/bin/tests/system/cleanpkcs11.sh +++ b/bin/tests/system/cleanpkcs11.sh @@ -18,4 +18,4 @@ if [ ! -x ../../pkcs11/pkcs11-destroy ]; then exit 1; fi -../../pkcs11/pkcs11-destroy -s 0 -p 1234 +../../pkcs11/pkcs11-destroy -s ${SLOT:-0} -p 1234 diff --git a/bin/tests/system/conf.sh.in b/bin/tests/system/conf.sh.in index d11f5cf9bb..d67470800a 100644 --- a/bin/tests/system/conf.sh.in +++ b/bin/tests/system/conf.sh.in @@ -45,9 +45,9 @@ DSFROMKEY=$TOP/bin/dnssec/dnssec-dsfromkey CHECKDS=$TOP/bin/python/dnssec-checkds CHECKZONE=$TOP/bin/check/named-checkzone CHECKCONF=$TOP/bin/check/named-checkconf -PK11GEN="$TOP/bin/pkcs11/pkcs11-keygen -s 0 -p 1234" -PK11LIST="$TOP/bin/pkcs11/pkcs11-list -s 0 -p 1234" -PK11DEL="$TOP/bin/pkcs11/pkcs11-destroy -s 0 -p 1234" +PK11GEN="$TOP/bin/pkcs11/pkcs11-keygen -s ${SLOT:-0} -p 1234" +PK11LIST="$TOP/bin/pkcs11/pkcs11-list -s ${SLOT:-0} -p 1234" +PK11DEL="$TOP/bin/pkcs11/pkcs11-destroy -s ${SLOT:-0} -p 1234" JOURNALPRINT=$TOP/bin/tools/named-journalprint VERIFY=$TOP/bin/dnssec/dnssec-verify diff --git a/lib/dns/ds.c b/lib/dns/ds.c index 733f56e35a..e72ecbb6cc 100644 --- a/lib/dns/ds.c +++ b/lib/dns/ds.c @@ -92,13 +92,13 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, #define CHECK(x) \ if ((x) != 1) { \ EVP_MD_CTX_cleanup(&ctx); \ - return (DST_R_OPENSSLFAILURE); \ + return (DST_R_CRYPTOFAILURE); \ } case DNS_DSDIGEST_GOST: md = EVP_gost(); if (md == NULL) - return (DST_R_OPENSSLFAILURE); + return (DST_R_CRYPTOFAILURE); EVP_MD_CTX_init(&ctx); CHECK(EVP_DigestInit(&ctx, md)); dns_name_toregion(name, &r); diff --git a/lib/dns/dst_openssl.h b/lib/dns/dst_openssl.h index cc9929fc20..11d41d95fc 100644 --- a/lib/dns/dst_openssl.h +++ b/lib/dns/dst_openssl.h @@ -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); diff --git a/lib/dns/dst_result.c b/lib/dns/dst_result.c index 429dbb2fc1..d5ee38d169 100644 --- a/lib/dns/dst_result.c +++ b/lib/dns/dst_result.c @@ -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 */ diff --git a/lib/dns/include/dns/log.h b/lib/dns/include/dns/log.h index 2060a33c6f..67f0a81bf7 100644 --- a/lib/dns/include/dns/log.h +++ b/lib/dns/include/dns/log.h @@ -75,6 +75,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 diff --git a/lib/dns/include/dst/result.h b/lib/dns/include/dst/result.h index d77b72e77a..9b6389d11d 100644 --- a/lib/dns/include/dst/result.h +++ b/lib/dns/include/dst/result.h @@ -34,7 +34,9 @@ #include /* 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) diff --git a/lib/dns/log.c b/lib/dns/log.c index e6fbb53a44..9f4887a09c 100644 --- a/lib/dns/log.c +++ b/lib/dns/log.c @@ -81,6 +81,7 @@ LIBDNS_EXTERNAL_DATA isc_logmodule_t dns_modules[] = { { "dns/acache", 0 }, { "dns/dlz", 0 }, { "dns/dnssec", 0 }, + { "dns/crypto", 0 }, { NULL, 0 } }; diff --git a/lib/dns/openssl_link.c b/lib/dns/openssl_link.c index 59626f2039..6cc903549a 100644 --- a/lib/dns/openssl_link.c +++ b/lib/dns/openssl_link.c @@ -45,6 +45,8 @@ #include #include +#include + #include #include "dst_internal.h" @@ -172,6 +174,8 @@ dst__openssl_init(const char *engine) { 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; @@ -285,7 +289,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: @@ -298,6 +302,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 *engine) { diff --git a/lib/dns/openssldh_link.c b/lib/dns/openssldh_link.c index 3296b91c51..36b8a412a3 100644 --- a/lib/dns/openssldh_link.c +++ b/lib/dns/openssldh_link.c @@ -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); } @@ -204,7 +205,7 @@ openssldh_generate(dst_key_t *key, int generator, void (*callback)(int)) { #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)); if (callback == NULL) { BN_GENCB_set_old(&cb, NULL, NULL); @@ -216,7 +217,9 @@ openssldh_generate(dst_key_t *key, int generator, void (*callback)(int)) { 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, @@ -225,11 +228,13 @@ openssldh_generate(dst_key_t *key, int generator, void (*callback)(int)) { } 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; @@ -460,6 +465,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) { diff --git a/lib/dns/openssldsa_link.c b/lib/dns/openssldsa_link.c index b7ee60c1bf..715fa73a2a 100644 --- a/lib/dns/openssldsa_link.c +++ b/lib/dns/openssldsa_link.c @@ -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 @@ -370,19 +379,22 @@ openssldsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { &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; diff --git a/lib/dns/opensslecdsa_link.c b/lib/dns/opensslecdsa_link.c index eec51a2e00..ad62865020 100644 --- a/lib/dns/opensslecdsa_link.c +++ b/lib/dns/opensslecdsa_link.c @@ -73,7 +73,8 @@ opensslecdsa_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; @@ -102,7 +103,8 @@ opensslecdsa_adddata(dst_context_t *dctx, const isc_region_t *data) { dctx->key->key_alg == DST_ALG_ECDSA384); if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) - return (ISC_R_FAILURE); + return (dst__openssl_toresult2("EVP_DigestUpdate", + ISC_R_FAILURE)); return (ISC_R_SUCCESS); } @@ -145,11 +147,13 @@ opensslecdsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { DST_RET(ISC_R_NOSPACE); if (!EVP_DigestFinal(evp_md_ctx, digest, &dgstlen)) - DST_RET(ISC_R_FAILURE); + DST_RET(dst__openssl_toresult2("EVP_DigestFinal", + ISC_R_FAILURE)); ecdsasig = ECDSA_do_sign(digest, dgstlen, eckey); if (ecdsasig == NULL) - DST_RET(dst__openssl_toresult(DST_R_SIGNFAILURE)); + DST_RET(dst__openssl_toresult2("ECDSA_do_sign", + DST_R_SIGNFAILURE)); BN_bn2bin_fixed(ecdsasig->r, r.base, siglen / 2); r.base += siglen / 2; BN_bn2bin_fixed(ecdsasig->s, r.base, siglen / 2); @@ -192,7 +196,8 @@ opensslecdsa_verify(dst_context_t *dctx, const isc_region_t *sig) { return (DST_R_VERIFYFAILURE); if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &dgstlen)) - DST_RET (ISC_R_FAILURE); + DST_RET (dst__openssl_toresult2("EVP_DigestFinal_ex", + ISC_R_FAILURE)); ecdsasig = ECDSA_SIG_new(); if (ecdsasig == NULL) @@ -203,9 +208,18 @@ opensslecdsa_verify(dst_context_t *dctx, const isc_region_t *sig) { /* cp += siglen / 2; */ status = ECDSA_do_verify(digest, dgstlen, ecdsasig, eckey); - if (status != 1) - DST_RET (dst__openssl_toresult(DST_R_VERIFYFAILURE)); - ret = ISC_R_SUCCESS; + switch (status) { + case 1: + ret = ISC_R_SUCCESS; + break; + case 0: + ret = dst__openssl_toresult(DST_R_VERIFYFAILURE); + break; + default: + ret = dst__openssl_toresult2("ECDSA_do_verify", + DST_R_VERIFYFAILURE); + break; + } err: if (ecdsasig != NULL) @@ -278,10 +292,12 @@ opensslecdsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { eckey = EC_KEY_new_by_curve_name(group_nid); if (eckey == NULL) - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + return (dst__openssl_toresult2("EC_KEY_new_by_curve_name", + DST_R_OPENSSLFAILURE)); if (EC_KEY_generate_key(eckey) != 1) - DST_RET (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + DST_RET (dst__openssl_toresult2("EC_KEY_generate_key", + DST_R_OPENSSLFAILURE)); pkey = EVP_PKEY_new(); if (pkey == NULL) @@ -334,7 +350,7 @@ opensslecdsa_todns(const dst_key_t *key, isc_buffer_t *data) { pkey = key->keydata.pkey; eckey = EVP_PKEY_get1_EC_KEY(pkey); if (eckey == NULL) - return (ISC_R_FAILURE); + return (dst__openssl_toresult(ISC_R_FAILURE)); len = i2o_ECPublicKey(eckey, NULL); /* skip form */ len--; @@ -344,7 +360,7 @@ opensslecdsa_todns(const dst_key_t *key, isc_buffer_t *data) { DST_RET (ISC_R_NOSPACE); cp = buf; if (!i2o_ECPublicKey(eckey, &cp)) - DST_RET (ISC_R_FAILURE); + DST_RET (dst__openssl_toresult(ISC_R_FAILURE)); memcpy(r.base, buf + 1, len); isc_buffer_add(data, len); ret = ISC_R_SUCCESS; @@ -393,16 +409,16 @@ opensslecdsa_fromdns(dst_key_t *key, isc_buffer_t *data) { if (o2i_ECPublicKey(&eckey, (const unsigned char **) &cp, (long) len + 1) == NULL) - DST_RET (DST_R_INVALIDPUBLICKEY); + DST_RET (dst__openssl_toresult(DST_R_INVALIDPUBLICKEY)); if (EC_KEY_check_key(eckey) != 1) - DST_RET (DST_R_INVALIDPUBLICKEY); + DST_RET (dst__openssl_toresult(DST_R_INVALIDPUBLICKEY)); pkey = EVP_PKEY_new(); if (pkey == NULL) DST_RET (ISC_R_NOMEMORY); if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) { EVP_PKEY_free(pkey); - DST_RET (ISC_R_FAILURE); + DST_RET (dst__openssl_toresult(ISC_R_FAILURE)); } isc_buffer_forward(data, len); @@ -430,7 +446,7 @@ opensslecdsa_tofile(const dst_key_t *key, const char *directory) { pkey = key->keydata.pkey; eckey = EVP_PKEY_get1_EC_KEY(pkey); if (eckey == NULL) - return (ISC_R_FAILURE); + return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); privkey = EC_KEY_get0_private_key(eckey); if (privkey == NULL) DST_RET (ISC_R_FAILURE); @@ -527,7 +543,7 @@ opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { DST_RET (ISC_R_NOMEMORY); if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) { EVP_PKEY_free(pkey); - DST_RET (ISC_R_FAILURE); + DST_RET (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); } key->keydata.pkey = pkey; ret = ISC_R_SUCCESS; diff --git a/lib/dns/opensslgost_link.c b/lib/dns/opensslgost_link.c index 27e27abb23..1ca8980812 100644 --- a/lib/dns/opensslgost_link.c +++ b/lib/dns/opensslgost_link.c @@ -121,10 +121,15 @@ opensslgost_verify(dst_context_t *dctx, const isc_region_t *sig) { EVP_PKEY *pkey = key->keydata.pkey; status = EVP_VerifyFinal(evp_md_ctx, sig->base, sig->length, pkey); - 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("EVP_VerifyFinal", + DST_R_VERIFYFAILURE)); + } } static isc_boolean_t @@ -168,22 +173,27 @@ opensslgost_generate(dst_key_t *key, int unused, void (*callback)(int)) { void (*fptr)(int); } u; EVP_PKEY *pkey = NULL; + isc_result_t ret; UNUSED(unused); ctx = EVP_PKEY_CTX_new_id(NID_id_GostR3410_2001, NULL); if (ctx == NULL) - goto err; + DST_RET(dst__openssl_toresult2("EVP_PKEY_CTX_new_id", + DST_R_OPENSSLFAILURE)); if (callback != NULL) { u.fptr = callback; EVP_PKEY_CTX_set_app_data(ctx, u.dptr); EVP_PKEY_CTX_set_cb(ctx, &progress_cb); } if (EVP_PKEY_keygen_init(ctx) <= 0) - goto err; + DST_RET(dst__openssl_toresult2("EVP_PKEY_keygen_init", + DST_R_OPENSSLFAILURE)); if (EVP_PKEY_CTX_ctrl_str(ctx, "paramset", "A") <= 0) - goto err; + DST_RET(dst__openssl_toresult2("EVP_PKEY_CTX_ctrl_str", + DST_R_OPENSSLFAILURE)); if (EVP_PKEY_keygen(ctx, &pkey) <= 0) - goto err; + DST_RET(dst__openssl_toresult2("EVP_PKEY_keygen", + DST_R_OPENSSLFAILURE)); key->keydata.pkey = pkey; EVP_PKEY_CTX_free(ctx); return (ISC_R_SUCCESS); @@ -193,7 +203,7 @@ err: EVP_PKEY_free(pkey); if (ctx != NULL) EVP_PKEY_CTX_free(ctx); - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + return (ret); } static isc_boolean_t @@ -267,7 +277,8 @@ opensslgost_fromdns(dst_key_t *key, isc_buffer_t *data) { p = der; if (d2i_PUBKEY(&pkey, &p, (long) sizeof(der)) == NULL) - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + return (dst__openssl_toresult2("d2i_PUBKEY", + DST_R_OPENSSLFAILURE)); key->keydata.pkey = pkey; return (ISC_R_SUCCESS); @@ -293,7 +304,8 @@ opensslgost_tofile(const dst_key_t *key, const char *directory) { p = der; if (i2d_PrivateKey(pkey, &p) != len) { - result = dst__openssl_toresult(DST_R_OPENSSLFAILURE); + result = dst__openssl_toresult2("i2d_PrivateKey", + DST_R_OPENSSLFAILURE); goto fail; } @@ -328,7 +340,8 @@ opensslgost_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { p = priv.elements[0].data; if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p, (long) priv.elements[0].length) == NULL) - DST_RET(DST_R_INVALIDPRIVATEKEY); + DST_RET(dst__openssl_toresult2("d2i_PrivateKey", + DST_R_INVALIDPRIVATEKEY)); key->keydata.pkey = pkey; key->key_size = EVP_PKEY_bits(pkey); dst__privstruct_free(&priv, mctx); @@ -378,35 +391,47 @@ static dst_func_t opensslgost_functions = { isc_result_t dst__opensslgost_init(dst_func_t **funcp) { + isc_result_t ret; + REQUIRE(funcp != NULL); /* check if the gost engine works properly */ e = ENGINE_by_id("gost"); if (e == NULL) - return (DST_R_OPENSSLFAILURE); + return (dst__openssl_toresult2("ENGINE_by_id", + DST_R_OPENSSLFAILURE)); if (ENGINE_init(e) <= 0) { ENGINE_free(e); e = NULL; - return (DST_R_OPENSSLFAILURE); + return (dst__openssl_toresult2("ENGINE_init", + DST_R_OPENSSLFAILURE)); } /* better than to rely on digest_gost symbol */ opensslgost_digest = ENGINE_get_digest(e, NID_id_GostR3411_94); + if (opensslgost_digest == NULL) + DST_RET(dst__openssl_toresult2("ENGINE_get_digest", + DST_R_OPENSSLFAILURE)); /* from openssl.cnf */ - if ((opensslgost_digest == NULL) || - (ENGINE_register_pkey_asn1_meths(e) <= 0) || - (ENGINE_ctrl_cmd_string(e, - "CRYPT_PARAMS", - "id-Gost28147-89-CryptoPro-A-ParamSet", - 0) <= 0)) { - ENGINE_finish(e); - ENGINE_free(e); - e = NULL; - return (DST_R_OPENSSLFAILURE); - } + if (ENGINE_register_pkey_asn1_meths(e) <= 0) + DST_RET(dst__openssl_toresult2( + "ENGINE_register_pkey_asn1_meths", + DST_R_OPENSSLFAILURE)); + if (ENGINE_ctrl_cmd_string(e, + "CRYPT_PARAMS", + "id-Gost28147-89-CryptoPro-A-ParamSet", + 0) <= 0) + DST_RET(dst__openssl_toresult2("ENGINE_ctrl_cmd_string", + DST_R_OPENSSLFAILURE)); if (*funcp == NULL) *funcp = &opensslgost_functions; return (ISC_R_SUCCESS); + + err: + ENGINE_finish(e); + ENGINE_free(e); + e = NULL; + return (ret); } #else /* HAVE_OPENSSL_GOST */ diff --git a/lib/dns/opensslrsa_link.c b/lib/dns/opensslrsa_link.c index fa6b7d615b..891daf0726 100644 --- a/lib/dns/opensslrsa_link.c +++ b/lib/dns/opensslrsa_link.c @@ -163,7 +163,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 @@ -311,7 +312,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) { @@ -381,7 +383,6 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { int status; int type = 0; unsigned int digestlen = 0; - char *message; unsigned long err; const char* file; int line; @@ -404,7 +405,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)) @@ -496,13 +498,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); @@ -635,7 +633,9 @@ opensslrsa_verify2(dst_context_t *dctx, int maxbits, 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)) @@ -656,7 +656,8 @@ opensslrsa_verify2(dst_context_t *dctx, int maxbits, 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); } @@ -751,6 +752,7 @@ progress_cb(int p, int n, BN_GENCB *cb) static isc_result_t opensslrsa_generate(dst_key_t *key, int exp, void (*callback)(int)) { + isc_result_t ret = DST_R_OPENSSLFAILURE; #if OPENSSL_VERSION_NUMBER > 0x00908000L BN_GENCB cb; union { @@ -801,6 +803,8 @@ opensslrsa_generate(dst_key_t *key, int exp, void (*callback)(int)) { #endif return (ISC_R_SUCCESS); } + ret = dst__openssl_toresult2("RSA_generate_key_ex", + DST_R_OPENSSLFAILURE); err: #if USE_EVP @@ -811,7 +815,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; @@ -835,7 +839,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 @@ -1034,6 +1039,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) { @@ -1187,7 +1193,7 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { /* 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) { @@ -1213,10 +1219,10 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { 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, engine); if (key->engine == NULL) DST_RET(ISC_R_NOMEMORY); @@ -1365,7 +1371,8 @@ opensslrsa_fromlabel(dst_key_t *key, const char *engine, const char *label, } 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)); if (engine != NULL) { key->engine = isc_mem_strdup(key->mctx, engine); if (key->engine == NULL)