From c3079c2b81b95d1cec1580a7bd0281924b7abc6a Mon Sep 17 00:00:00 2001 From: Petr Mensik Date: Tue, 18 Oct 2022 19:55:01 +0200 Subject: [PATCH 1/3] Allow running unittest with verbosity logs enabled It were possible to enable them only from debugger. Allow setting them from command line also. --- testcode/unitmain.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/testcode/unitmain.c b/testcode/unitmain.c index b6dac5507..fca2db030 100644 --- a/testcode/unitmain.c +++ b/testcode/unitmain.c @@ -863,8 +863,12 @@ main(int argc, char* argv[]) { checklock_start(); log_init(NULL, 0, NULL); - if(argc != 1) { - printf("usage: %s\n", argv[0]); + if (argc == 2 && strcmp(argv[1], "-v") == 0) { + verbosity = VERB_ALGO; + } + if(argc != 1 && verbosity != VERB_ALGO) { + printf("usage: [-v] %s\n", argv[0]); + printf("-v\tprint verbose logs.\n"); printf("\tperforms unit tests.\n"); return 1; } From 0b47b6a7761edc121b738bcb59f5a69c9f11f08b Mon Sep 17 00:00:00 2001 From: Petr Mensik Date: Wed, 12 Oct 2022 13:35:58 +0200 Subject: [PATCH 2/3] Make unittest pass on system with SHA1 unavailable CentOS 9 has disabled SHA-1 validation by default. It makes possible passing of unit tests on such system. Make it possible to process also indeterminate result from rrset validation. It would mean that signature is not known bogus, but were not able to be validated at the same time. --- testcode/unitverify.c | 10 +++++--- validator/val_sigcrypt.c | 54 ++++++++++++++++++++++++++++++---------- validator/val_sigcrypt.h | 11 +++++--- 3 files changed, 55 insertions(+), 20 deletions(-) diff --git a/testcode/unitverify.c b/testcode/unitverify.c index ff069a1bb..71b74d29b 100644 --- a/testcode/unitverify.c +++ b/testcode/unitverify.c @@ -193,10 +193,12 @@ verifytest_rrset(struct module_env* env, struct val_env* ve, printf("verify outcome is: %s %s\n", sec_status_to_string(sec), reason?reason:""); } - if(should_be_bogus(rrset, qinfo)) { - unit_assert(sec == sec_status_bogus); - } else { - unit_assert(sec == sec_status_secure); + if (sec != sec_status_indeterminate) { + if(should_be_bogus(rrset, qinfo)) { + unit_assert(sec == sec_status_bogus); + } else { + unit_assert(sec == sec_status_secure); + } } } diff --git a/validator/val_sigcrypt.c b/validator/val_sigcrypt.c index 5ab21e20e..45c8fe927 100644 --- a/validator/val_sigcrypt.c +++ b/validator/val_sigcrypt.c @@ -440,8 +440,8 @@ void algo_needs_init_dnskey_add(struct algo_needs* n, algo = (uint8_t)dnskey_get_algo(dnskey, i); if(!dnskey_algo_id_is_supported((int)algo)) continue; - if(n->needs[algo] == 0) { - n->needs[algo] = 1; + if(n->needs[algo] == ALG_NEED_SECURE) { + n->needs[algo] = ALG_NEED_WAITING; sigalg[total] = algo; total++; } @@ -455,11 +455,11 @@ void algo_needs_init_list(struct algo_needs* n, uint8_t* sigalg) uint8_t algo; size_t total = 0; - memset(n->needs, 0, sizeof(uint8_t)*ALGO_NEEDS_MAX); + memset(n->needs, 0, sizeof(n->needs)); while( (algo=*sigalg++) != 0) { log_assert(dnskey_algo_id_is_supported((int)algo)); - log_assert(n->needs[algo] == 0); - n->needs[algo] = 1; + log_assert(n->needs[algo] == ALG_NEED_SECURE); + n->needs[algo] = ALG_NEED_WAITING; total++; } n->num = total; @@ -472,7 +472,7 @@ void algo_needs_init_ds(struct algo_needs* n, struct ub_packed_rrset_key* ds, size_t i, total = 0; size_t num = rrset_get_count(ds); - memset(n->needs, 0, sizeof(uint8_t)*ALGO_NEEDS_MAX); + memset(n->needs, 0, sizeof(n->needs)); for(i=0; ineeds[algo] == 0) { - n->needs[algo] = 1; + if(n->needs[algo] == ALG_NEED_SECURE) { + n->needs[algo] = ALG_NEED_WAITING; sigalg[total] = algo; total++; } @@ -492,8 +492,8 @@ void algo_needs_init_ds(struct algo_needs* n, struct ub_packed_rrset_key* ds, int algo_needs_set_secure(struct algo_needs* n, uint8_t algo) { - if(n->needs[algo]) { - n->needs[algo] = 0; + if(n->needs[algo] >= ALG_NEED_WAITING) { + n->needs[algo] = ALG_NEED_SECURE; n->num --; if(n->num == 0) /* done! */ return 1; @@ -501,9 +501,16 @@ int algo_needs_set_secure(struct algo_needs* n, uint8_t algo) return 0; } +static void algo_needs_set_indeterminate(struct algo_needs* n, uint8_t algo) +{ + if(n->needs[algo] == ALG_NEED_WAITING) + n->needs[algo] = ALG_NEED_INDETERMINATE; +} + void algo_needs_set_bogus(struct algo_needs* n, uint8_t algo) { - if(n->needs[algo]) n->needs[algo] = 2; /* need it, but bogus */ + if(n->needs[algo] >= ALG_NEED_WAITING) + n->needs[algo] = ALG_NEED_BOGUS; /* need it, but bogus */ } size_t algo_needs_num_missing(struct algo_needs* n) @@ -518,15 +525,28 @@ int algo_needs_missing(struct algo_needs* n) * check the first missing algo - report that; * or return 0 */ for(i=0; ineeds[i] == 2) + if(n->needs[i] == ALG_NEED_BOGUS) return 0; - if(n->needs[i] == 1 && miss == -1) + if(n->needs[i] == ALG_NEED_WAITING && miss == -1) miss = i; } if(miss != -1) return miss; return 0; } +static size_t algo_needs_num_indeterminate(struct algo_needs* n) +{ + int i, num = 0; + /* report number of indeterminate results if not bogus */ + for(i=0; ineeds[i] == ALG_NEED_BOGUS) + return 0; + if(n->needs[i] == ALG_NEED_INDETERMINATE) + num++; + } + return num; +} + /** * verify rrset, with dnskey rrset, for a specific rrsig in rrset * @param env: module environment, scratch space is used. @@ -648,6 +668,9 @@ dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve, else if(algo_needs_set_secure(&needs, (uint8_t)rrset_get_sig_algo(rrset, i))) return sec; /* done! */ + } else if(sec == sec_status_indeterminate) { + algo_needs_set_indeterminate(&needs, + (uint8_t)rrset_get_sig_algo(rrset, i)); } else if(sigalg && sec == sec_status_bogus) { algo_needs_set_bogus(&needs, (uint8_t)rrset_get_sig_algo(rrset, i)); @@ -658,6 +681,11 @@ dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve, "no valid signatures for %d algorithms", (int)algo_needs_num_missing(&needs)); algo_needs_reason(env, alg, reason, "no signatures"); + } else if (sigalg && (num=algo_needs_num_indeterminate(&needs)) > 0) { + verbose(VERB_ALGO, "rrset failed to verify: " + "indeterminate signatures for %d algorithms", + (int)num); + return sec_status_indeterminate; } else { verbose(VERB_ALGO, "rrset failed to verify: " "no valid signatures"); diff --git a/validator/val_sigcrypt.h b/validator/val_sigcrypt.h index 7f52b71e4..a4802f55d 100644 --- a/validator/val_sigcrypt.h +++ b/validator/val_sigcrypt.h @@ -57,14 +57,19 @@ struct sldns_buffer; /** number of entries in algorithm needs array */ #define ALGO_NEEDS_MAX 256 +enum algo_needs_types { + ALG_NEED_SECURE = 0, /*< not marked */ + ALG_NEED_WAITING, /*< marked 'necessary but not yet fulfilled' */ + ALG_NEED_INDETERMINATE, + ALG_NEED_BOGUS, /*< marked bogus */ +}; + /** * Storage for algorithm needs. DNSKEY algorithms. */ struct algo_needs { /** the algorithms (8-bit) with each a number. - * 0: not marked. - * 1: marked 'necessary but not yet fulfilled' - * 2: marked bogus. + * contains enum algo_needs_types values. * Indexed by algorithm number. */ uint8_t needs[ALGO_NEEDS_MAX]; From d08cb03b8ff699b2f689a1a2f72438849eeb9d2a Mon Sep 17 00:00:00 2001 From: Petr Mensik Date: Wed, 19 Oct 2022 19:59:29 +0200 Subject: [PATCH 3/3] Read all pushed errors from openssl RHEL 9 with DEFAULT crypto policy produces 3 errors pushed to the error stack in one failed case. Ensure it does not break following tests, but all of them are read after the call failure. --- validator/val_secalgo.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/validator/val_secalgo.c b/validator/val_secalgo.c index 786516749..470703589 100644 --- a/validator/val_secalgo.c +++ b/validator/val_secalgo.c @@ -702,16 +702,19 @@ digest_ctx_free(EVP_MD_CTX* ctx, EVP_PKEY *evp_key, static enum sec_status digest_error_status(const char *str) { - unsigned long e = ERR_get_error(); + enum sec_status r = sec_status_unchecked; + unsigned long e; + while ((e = ERR_get_error()) != 0) { #ifdef EVP_R_INVALID_DIGEST - if (ERR_GET_LIB(e) == ERR_LIB_EVP && - ERR_GET_REASON(e) == EVP_R_INVALID_DIGEST) { - log_crypto_verbose(VERB_ALGO, str, e); - return sec_status_indeterminate; - } + if (ERR_GET_LIB(e) == ERR_LIB_EVP && + ERR_GET_REASON(e) == EVP_R_INVALID_DIGEST) { + log_crypto_verbose(VERB_ALGO, str, e); + r = sec_status_indeterminate; + } else #endif - log_crypto_verbose(VERB_QUERY, str, e); - return sec_status_unchecked; + log_crypto_verbose(VERB_QUERY, str, e); + } + return r; } /**