Commit 13e435eb authored by Giovanni Bajo's avatar Giovanni Bajo Committed by Simon Kelley

Bugfix: domain names must go through hash function in DNS format (but uncompressed!)

parent 4b0eecbb
...@@ -103,6 +103,27 @@ typedef struct PendingRRSIGValidation ...@@ -103,6 +103,27 @@ typedef struct PendingRRSIGValidation
int keytag; int keytag;
} PendingRRSIGValidation; } PendingRRSIGValidation;
/* Pass a domain name through a verification hash function.
We must pass domain names in DNS wire format, but uncompressed.
This means that we cannot directly use raw data from the original
message since it might be compressed. */
static void verifyalg_add_data_domain(VerifyAlgCtx *alg, char* name)
{
unsigned char len; char *p;
while ((p = strchr(name, '.')))
{
len = p-name;
alg->vtbl->add_data(alg, &len, 1);
alg->vtbl->add_data(alg, name, len);
name = p+1;
}
len = strlen(name);
alg->vtbl->add_data(alg, &len, 1);
alg->vtbl->add_data(alg, name, len+1);
}
static int begin_rrsig_validation(struct dns_header *header, size_t pktlen, static int begin_rrsig_validation(struct dns_header *header, size_t pktlen,
unsigned char *reply, int count, char *owner, unsigned char *reply, int count, char *owner,
int sigclass, int sigrdlen, unsigned char *sig, int sigclass, int sigrdlen, unsigned char *sig,
...@@ -114,6 +135,7 @@ static int begin_rrsig_validation(struct dns_header *header, size_t pktlen, ...@@ -114,6 +135,7 @@ static int begin_rrsig_validation(struct dns_header *header, size_t pktlen,
unsigned long sigttl, date_end, date_start; unsigned long sigttl, date_end, date_start;
unsigned char* p = reply; unsigned char* p = reply;
char* signer_name = daemon->namebuff; char* signer_name = daemon->namebuff;
int signer_name_rdlen;
int keytag; int keytag;
void *rrset[16]; /* TODO: max RRset size? */ void *rrset[16]; /* TODO: max RRset size? */
int rrsetidx = 0; int rrsetidx = 0;
...@@ -169,10 +191,10 @@ static int begin_rrsig_validation(struct dns_header *header, size_t pktlen, ...@@ -169,10 +191,10 @@ static int begin_rrsig_validation(struct dns_header *header, size_t pktlen,
qsort(rrset, rrsetidx, sizeof(void*), rrset_canonical_order); qsort(rrset, rrsetidx, sizeof(void*), rrset_canonical_order);
/* Extract the signer name (we need to query DNSKEY of this name) */ /* Extract the signer name (we need to query DNSKEY of this name) */
if (!(res = extract_name_no_compression(sig, sigrdlen, signer_name))) if (!(signer_name_rdlen = extract_name_no_compression(sig, sigrdlen, signer_name)))
return 0; return 0;
sig += res; sigrdlen -= res; sig += signer_name_rdlen; sigrdlen -= signer_name_rdlen;
/* Now initialize the signature verification algorithm and process the whole /* Now initialize the signature verification algorithm and process the whole
RRset */ RRset */
VerifyAlgCtx *alg = verifyalg_alloc(sigalg); VerifyAlgCtx *alg = verifyalg_alloc(sigalg);
...@@ -186,18 +208,17 @@ static int begin_rrsig_validation(struct dns_header *header, size_t pktlen, ...@@ -186,18 +208,17 @@ static int begin_rrsig_validation(struct dns_header *header, size_t pktlen,
sigttl = htonl(sigttl); sigttl = htonl(sigttl);
alg->vtbl->begin_data(alg); alg->vtbl->begin_data(alg);
alg->vtbl->add_data(alg, sigrdata, 18); alg->vtbl->add_data(alg, sigrdata, 18+signer_name_rdlen);
alg->vtbl->add_data(alg, signer_name, strlen(signer_name));
for (i = 0; i < rrsetidx; ++i) for (i = 0; i < rrsetidx; ++i)
{ {
int rdlen; int rdlen;
p = (unsigned char*)(rrset[i]);
alg->vtbl->add_data(alg, owner, strlen(owner));
verifyalg_add_data_domain(alg, owner);
alg->vtbl->add_data(alg, &sigtype, 2); alg->vtbl->add_data(alg, &sigtype, 2);
alg->vtbl->add_data(alg, &sigclass, 2); alg->vtbl->add_data(alg, &sigclass, 2);
alg->vtbl->add_data(alg, &sigttl, 4); alg->vtbl->add_data(alg, &sigttl, 4);
p = (unsigned char*)(rrset[i]);
p += 8; p += 8;
GETSHORT(rdlen, p); GETSHORT(rdlen, p);
/* TODO: instead of a direct add_data(), we must call a RRtype-specific /* TODO: instead of a direct add_data(), we must call a RRtype-specific
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment