neater errors for algo and key failure.

git-svn-id: file:///svn/unbound/trunk@1872 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2009-10-08 08:02:00 +00:00
parent 7782cf2b97
commit 2c33330994

View file

@ -459,6 +459,21 @@ dnskeyset_needs(struct ub_packed_rrset_key* dnskey, uint8_t needs[])
return total;
}
/** see which algo needed */
static int any_needed_bogus(uint8_t needs[])
{
int i;
/* first check if a needed algo was bogus - report that */
for(i=0; i<256; i++)
if(needs[i] == 2)
return 0;
/* now check which algo is missing */
for(i=0; i<256; i++)
if(needs[i] == 1)
return i;
return 0;
}
enum sec_status
dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve,
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
@ -469,7 +484,7 @@ dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve,
rbtree_t* sortree = NULL;
/* make sure that for all DNSKEY algorithms there are valid sigs */
uint8_t needs[256]; /* 1 if need sig for that algorithm */
int sawbogus = 0;
int alg;
num = rrset_get_sigcount(rrset);
if(num == 0) {
@ -486,20 +501,31 @@ dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve,
/* see which algorithm has been fixed up */
if(sec == sec_status_secure) {
uint8_t a = (uint8_t)rrset_get_sig_algo(rrset, i);
if(needs[a] == 1) {
if(needs[a]) {
needs[a] = 0;
numneeds --;
if(numneeds == 0) /* done! */
return sec;
}
} else if(sec == sec_status_bogus) {
uint8_t a = (uint8_t)rrset_get_sig_algo(rrset, i);
if(needs[a]) needs[a] = 2; /* need it, but bogus */
}
else if(sec == sec_status_bogus)
sawbogus = 1;
}
verbose(VERB_ALGO, "rrset failed to verify: no valid signatures for "
"%d algorithms", (int)numneeds);
if(!sawbogus)
*reason = "no signatures for all algorithms";
if((alg=any_needed_bogus(needs)) != 0) {
char buf[256];
ldns_lookup_table *t = ldns_lookup_by_id(ldns_algorithms, alg);
if(t&&t->name)
snprintf(buf, sizeof(buf), "no signatures with "
"algorithm %s", t->name);
else snprintf(buf, sizeof(buf), "no signatures with "
"algorithm ALG%u", (unsigned)alg);
*reason = regional_strdup(env->scratch, buf);
if(!*reason)
*reason = "no signatures for all algorithms";
}
return sec_status_bogus;
}
@ -1372,12 +1398,14 @@ setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type,
* @param sigblock_len: length of sigblock data.
* @param key: public key data from DNSKEY RR.
* @param keylen: length of keydata.
* @param reason: bogus reason in more detail.
* @return secure if verification succeeded, bogus on crypto failure,
* unchecked on format errors and alloc failures.
*/
static enum sec_status
verify_canonrrset(ldns_buffer* buf, int algo, unsigned char* sigblock,
unsigned int sigblock_len, unsigned char* key, unsigned int keylen)
unsigned int sigblock_len, unsigned char* key, unsigned int keylen,
char** reason)
{
const EVP_MD *digest_type;
EVP_MD_CTX ctx;
@ -1386,6 +1414,7 @@ verify_canonrrset(ldns_buffer* buf, int algo, unsigned char* sigblock,
if(!setup_key_digest(algo, &evp_key, &digest_type, key, keylen)) {
verbose(VERB_QUERY, "verify: failed to setup key");
*reason = "use of key for crypto failed";
EVP_PKEY_free(evp_key);
return sec_status_bogus;
}
@ -1394,6 +1423,7 @@ verify_canonrrset(ldns_buffer* buf, int algo, unsigned char* sigblock,
sigblock_len == 1+2*SHA_DIGEST_LENGTH) {
if(!setup_dsa_sig(&sigblock, &sigblock_len)) {
verbose(VERB_QUERY, "verify: failed to setup DSA sig");
*reason = "use of key for DSA crypto failed";
EVP_PKEY_free(evp_key);
return sec_status_bogus;
}
@ -1432,6 +1462,7 @@ verify_canonrrset(ldns_buffer* buf, int algo, unsigned char* sigblock,
return sec_status_secure;
} else if(res == 0) {
verbose(VERB_QUERY, "verify: signature mismatch");
*reason = "signature crypto failed";
return sec_status_bogus;
}
@ -1564,13 +1595,12 @@ dnskey_verify_rrset_sig(struct regional* region, ldns_buffer* buf,
/* verify */
sec = verify_canonrrset(buf, (int)sig[2+2],
sigblock, sigblock_len, key, keylen);
sigblock, sigblock_len, key, keylen, reason);
/* check if TTL is too high - reduce if so */
if(sec == sec_status_secure) {
adjust_ttl(ve, now, rrset, sig+2+4, sig+2+8, sig+2+12);
} else if(sec == sec_status_bogus)
*reason = "signature crypto failed";
}
return sec;
}