+3354. [func] Improve OpenSSL error logging. [RT #29932]
+
3352. [bug] Ensure that learned server attributes timeout of the
adb cache. [RT #29856]
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);
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);
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));
t_info("isc_file_mktemplate failed %s\n",
isc_result_totext(ret));
++*nprobs;
- return;
+ goto cleanup;
}
ret = isc_dir_createunique(tmp);
t_info("isc_dir_createunique failed %s\n",
isc_result_totext(ret));
++*nprobs;
- return;
+ goto cleanup;
}
ret = dst_key_tofile(key1, type, tmp);
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);
t_info("dst_key_tofile(%d) returned: %s\n",
alg, dst_result_totext(ret));
++*nfails;
- return;
+ goto cleanup;
}
cleandir(tmp);
t_info("dst_computesecret() returned: %s\n",
dst_result_totext(ret));
++*nfails;
- return;
+ goto cleanup;
}
isc_buffer_init(&b2, array2, sizeof(array2));
t_info("dst_computesecret() returned: %s\n",
dst_result_totext(ret));
++*nfails;
- return;
+ goto cleanup;
}
isc_buffer_usedregion(&b1, &r1);
{
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
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
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)) ||
t_info("dst_context_verify returned %s, expected %s\n",
isc_result_totext(isc_result),
expected_result);
- dst_context_destroy(&ctx);
++*nfails;
}
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);
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 */
#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
#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)
{ "dns/acache", 0 },
{ "dns/dlz", 0 },
{ "dns/dnssec", 0 },
+ { "dns/crypto", 0 },
{ NULL, 0 }
};
/*
- * 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"
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;
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:
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) {
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);
}
#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,
}
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;
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) {
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);
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);
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
&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;
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
#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) {
int status = 0;
int type = 0;
unsigned int digestlen = 0;
- char *message;
unsigned long err;
const char* file;
int line;
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))
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);
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))
#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);
}
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();
#endif
return (ISC_R_SUCCESS);
}
+ ret = dst__openssl_toresult2("RSA_generate_key_ex",
+ DST_R_OPENSSLFAILURE);
err:
#if USE_EVP
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;
#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
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) {
/* 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) {
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);
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);