mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
rrsig checks.
git-svn-id: file:///svn/unbound/trunk@502 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
8f58908f45
commit
45f95a18af
11 changed files with 413 additions and 8 deletions
|
|
@ -1,3 +1,7 @@
|
|||
9 August 2007: Wouter
|
||||
- canonicalization, signature checks
|
||||
- dname signature label count and unit test.
|
||||
|
||||
8 August 2007: Wouter
|
||||
- ldns _raw routines created (in ldns trunk).
|
||||
- sigcrypt DS digest routines
|
||||
|
|
|
|||
|
|
@ -76,21 +76,21 @@ static void
|
|||
dname_test_qdtl(ldns_buffer* buff)
|
||||
{
|
||||
ldns_buffer_write_at(buff, 0, "\012abCDeaBCde\003cOm\000", 16);
|
||||
query_dname_tolower(ldns_buffer_begin(buff), 16);
|
||||
query_dname_tolower(ldns_buffer_begin(buff));
|
||||
unit_assert( memcmp(ldns_buffer_begin(buff),
|
||||
"\012abcdeabcde\003com\000", 16) == 0);
|
||||
|
||||
ldns_buffer_write_at(buff, 0, "\001+\012abC{e-ZYXe\003NET\000", 18);
|
||||
query_dname_tolower(ldns_buffer_begin(buff), 18);
|
||||
query_dname_tolower(ldns_buffer_begin(buff));
|
||||
unit_assert( memcmp(ldns_buffer_begin(buff),
|
||||
"\001+\012abc{e-zyxe\003net\000", 18) == 0);
|
||||
|
||||
ldns_buffer_write_at(buff, 0, "\000", 1);
|
||||
query_dname_tolower(ldns_buffer_begin(buff), 1);
|
||||
query_dname_tolower(ldns_buffer_begin(buff));
|
||||
unit_assert( memcmp(ldns_buffer_begin(buff), "\000", 1) == 0);
|
||||
|
||||
ldns_buffer_write_at(buff, 0, "\002NL\000", 4);
|
||||
query_dname_tolower(ldns_buffer_begin(buff), 4);
|
||||
query_dname_tolower(ldns_buffer_begin(buff));
|
||||
unit_assert( memcmp(ldns_buffer_begin(buff), "\002nl\000", 4) == 0);
|
||||
}
|
||||
|
||||
|
|
@ -463,6 +463,25 @@ dname_test_removelabel()
|
|||
unit_assert( l == 1 );
|
||||
}
|
||||
|
||||
/** test dname_signame_label_count */
|
||||
static void
|
||||
dname_test_sigcount()
|
||||
{
|
||||
unit_assert(dname_signame_label_count((uint8_t*)"\000") == 0);
|
||||
unit_assert(dname_signame_label_count((uint8_t*)"\001*\000") == 0);
|
||||
unit_assert(dname_signame_label_count((uint8_t*)"\003xom\000") == 1);
|
||||
unit_assert(dname_signame_label_count(
|
||||
(uint8_t*)"\001*\003xom\000") == 1);
|
||||
unit_assert(dname_signame_label_count(
|
||||
(uint8_t*)"\007example\003xom\000") == 2);
|
||||
unit_assert(dname_signame_label_count(
|
||||
(uint8_t*)"\001*\007example\003xom\000") == 2);
|
||||
unit_assert(dname_signame_label_count(
|
||||
(uint8_t*)"\003www\007example\003xom\000") == 3);
|
||||
unit_assert(dname_signame_label_count(
|
||||
(uint8_t*)"\001*\003www\007example\003xom\000") == 3);
|
||||
}
|
||||
|
||||
void dname_test()
|
||||
{
|
||||
ldns_buffer* buff = ldns_buffer_new(65800);
|
||||
|
|
@ -478,5 +497,6 @@ void dname_test()
|
|||
dname_test_subdomain();
|
||||
dname_test_isroot();
|
||||
dname_test_removelabel();
|
||||
dname_test_sigcount();
|
||||
ldns_buffer_free(buff);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ config_create()
|
|||
cfg->version = NULL;
|
||||
cfg->trust_anchor_file_list = NULL;
|
||||
cfg->trust_anchor_list = NULL;
|
||||
cfg->val_date_override = 0;
|
||||
if(!(cfg->module_conf = strdup("iterator"))) goto error_exit;
|
||||
return cfg;
|
||||
error_exit:
|
||||
|
|
|
|||
|
|
@ -144,6 +144,9 @@ struct config_file {
|
|||
/** list of trustanchor keys, linked list */
|
||||
struct config_strlist* trust_anchor_list;
|
||||
|
||||
/** if not 0, this value is the validation date for RRSIGs */
|
||||
int32_t val_date_override;
|
||||
|
||||
/** daemonize, i.e. fork into the background. */
|
||||
int do_daemonize;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -125,11 +125,10 @@ query_dname_compare(uint8_t* d1, uint8_t* d2)
|
|||
}
|
||||
|
||||
void
|
||||
query_dname_tolower(uint8_t* dname, size_t len)
|
||||
query_dname_tolower(uint8_t* dname)
|
||||
{
|
||||
/* the dname is stored uncompressed */
|
||||
uint8_t labellen;
|
||||
log_assert(len > 0);
|
||||
labellen = *dname;
|
||||
while(labellen) {
|
||||
dname++;
|
||||
|
|
@ -595,3 +594,22 @@ dname_remove_label(uint8_t** dname, size_t* len)
|
|||
*len -= lablen+1;
|
||||
*dname += lablen+1;
|
||||
}
|
||||
|
||||
int
|
||||
dname_signame_label_count(uint8_t* dname)
|
||||
{
|
||||
uint8_t lablen;
|
||||
int count = 0;
|
||||
if(!*dname)
|
||||
return 0;
|
||||
if(dname[0] == 1 && dname[1] == '*')
|
||||
dname += 2;
|
||||
lablen = dname[0];
|
||||
while(lablen) {
|
||||
count++;
|
||||
dname += lablen;
|
||||
dname += 1;
|
||||
lablen = dname[0];
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ size_t query_dname_len(ldns_buffer* query);
|
|||
size_t dname_valid(uint8_t* dname, size_t len);
|
||||
|
||||
/** lowercase query dname */
|
||||
void query_dname_tolower(uint8_t* dname, size_t len);
|
||||
void query_dname_tolower(uint8_t* dname);
|
||||
|
||||
/**
|
||||
* Compare query dnames (uncompressed storage). The Dnames passed do not
|
||||
|
|
@ -222,4 +222,11 @@ int dname_is_root(uint8_t* dname);
|
|||
*/
|
||||
void dname_remove_label(uint8_t** dname, size_t* len);
|
||||
|
||||
/**
|
||||
* Count labels for the RRSIG signature label field.
|
||||
* Like a normal labelcount, but "*" wildcard and "." root are not counted.
|
||||
* @param dname: valid uncompressed wireformat.
|
||||
*/
|
||||
int dname_signame_label_count(uint8_t* dname);
|
||||
|
||||
#endif /* UTIL_DATA_DNAME_H */
|
||||
|
|
|
|||
|
|
@ -72,6 +72,11 @@
|
|||
/** byte size of ip6 address */
|
||||
#define INET6_SIZE 16
|
||||
|
||||
/** DNSKEY zone sign key flag */
|
||||
#define DNSKEY_BIT_ZSK 0x10
|
||||
/** DNSKEY secure entry point, KSK flag */
|
||||
#define DNSKEY_BIT_SEP 0x01
|
||||
|
||||
/**
|
||||
* See if string is ip4 or ip6.
|
||||
* @param str: IP specification.
|
||||
|
|
|
|||
|
|
@ -42,9 +42,11 @@
|
|||
*/
|
||||
#include "config.h"
|
||||
#include "validator/val_sigcrypt.h"
|
||||
#include "validator/validator.h"
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/data/dname.h"
|
||||
#include "util/module.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/region-allocator.h"
|
||||
|
||||
#ifndef HAVE_SSL
|
||||
|
|
@ -116,6 +118,20 @@ rrset_get_rdata(struct ub_packed_rrset_key* k, size_t idx, uint8_t** rdata,
|
|||
*len = d->rr_len[idx];
|
||||
}
|
||||
|
||||
uint16_t
|
||||
dnskey_get_flags(struct ub_packed_rrset_key* k, size_t idx)
|
||||
{
|
||||
uint8_t* rdata;
|
||||
size_t len;
|
||||
uint16_t f;
|
||||
rrset_get_rdata(k, idx, &rdata, &len);
|
||||
if(len < 2+2)
|
||||
return 0;
|
||||
memmove(&f, rdata+2, 2);
|
||||
f = ntohs(f);
|
||||
return f;
|
||||
}
|
||||
|
||||
int
|
||||
dnskey_get_algo(struct ub_packed_rrset_key* k, size_t idx)
|
||||
{
|
||||
|
|
@ -244,7 +260,7 @@ ds_create_dnskey_digest(struct module_env* env,
|
|||
ldns_buffer_clear(b);
|
||||
ldns_buffer_write(b, dnskey_rrset->rk.dname,
|
||||
dnskey_rrset->rk.dname_len);
|
||||
query_dname_tolower(ldns_buffer_begin(b), dnskey_rrset->rk.dname_len);
|
||||
query_dname_tolower(ldns_buffer_begin(b));
|
||||
ldns_buffer_write(b, dnskey_rdata+2, dnskey_len-2); /* skip rdatalen*/
|
||||
ldns_buffer_flip(b);
|
||||
|
||||
|
|
@ -416,20 +432,337 @@ dnskeyset_verify_rrset_sig(struct module_env* env, struct val_env* ve,
|
|||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort RRs for rrset in canonical order.
|
||||
* Does not actually canonicalize the RR rdatas.
|
||||
* Does not touch rrsigs.
|
||||
* @param rrset: to sort.
|
||||
*/
|
||||
static void
|
||||
canonical_sort(struct ub_packed_rrset_key* rrset)
|
||||
{
|
||||
/* check if already sorted */
|
||||
/* remove duplicates */
|
||||
}
|
||||
|
||||
/**
|
||||
* Inser canonical owner name into buffer.
|
||||
* @param buf: buffer to insert into at current position.
|
||||
* @param k: rrset with its owner name.
|
||||
* @param sig: signature with signer name and label count.
|
||||
* must be length checked, at least 18 bytes long.
|
||||
* @param can_owner: position in buffer returned for future use.
|
||||
* @param can_owner_len: length of canonical owner name.
|
||||
*/
|
||||
static void
|
||||
insert_can_owner(ldns_buffer* buf, struct ub_packed_rrset_key* k,
|
||||
uint8_t* sig, uint8_t** can_owner, size_t* can_owner_len)
|
||||
{
|
||||
int rrsig_labels = (int)sig[3];
|
||||
int fqdn_labels = dname_signame_label_count(k->rk.dname);
|
||||
*can_owner = ldns_buffer_current(buf);
|
||||
if(rrsig_labels == fqdn_labels) {
|
||||
/* no change */
|
||||
ldns_buffer_write(buf, k->rk.dname, k->rk.dname_len);
|
||||
query_dname_tolower(*can_owner);
|
||||
*can_owner_len = k->rk.dname_len;
|
||||
return;
|
||||
}
|
||||
log_assert(rrsig_labels < fqdn_labels);
|
||||
/* *. | fqdn(rightmost rrsig_labels) */
|
||||
if(rrsig_labels < fqdn_labels) {
|
||||
int i;
|
||||
uint8_t* nm = k->rk.dname;
|
||||
size_t len = k->rk.dname_len;
|
||||
/* so skip fqdn_labels-rrsig_labels */
|
||||
for(i=0; i<fqdn_labels-rrsig_labels; i++) {
|
||||
dname_remove_label(&nm, &len);
|
||||
}
|
||||
*can_owner_len = len+2;
|
||||
ldns_buffer_write(buf, (uint8_t*)"\001*", 2);
|
||||
ldns_buffer_write(buf, nm, len);
|
||||
query_dname_tolower(*can_owner);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lowercase a text rdata field in a buffer.
|
||||
* @param p: pointer to start of text field (length byte).
|
||||
*/
|
||||
static void
|
||||
lowercase_text_field(uint8_t* p)
|
||||
{
|
||||
int i, len = (int)*p;
|
||||
p++;
|
||||
for(i=0; i<len; i++) {
|
||||
*p = (uint8_t)tolower((int)*p);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Canonicalize Rdata in buffer.
|
||||
* @param buf: buffer at position just after the rdata.
|
||||
* @param rrset: rrset with type.
|
||||
* @param len: length of the rdata (including rdatalen uint16).
|
||||
*/
|
||||
static void
|
||||
canonicalize_rdata(ldns_buffer* buf, struct ub_packed_rrset_key* rrset,
|
||||
size_t len)
|
||||
{
|
||||
uint8_t* datstart = ldns_buffer_current(buf)-len+2;
|
||||
switch(ntohs(rrset->rk.type)) {
|
||||
case LDNS_RR_TYPE_NXT:
|
||||
case LDNS_RR_TYPE_NSEC: /* type starts with the name */
|
||||
case LDNS_RR_TYPE_NS:
|
||||
case LDNS_RR_TYPE_MD:
|
||||
case LDNS_RR_TYPE_MF:
|
||||
case LDNS_RR_TYPE_CNAME:
|
||||
case LDNS_RR_TYPE_MB:
|
||||
case LDNS_RR_TYPE_MG:
|
||||
case LDNS_RR_TYPE_MR:
|
||||
case LDNS_RR_TYPE_PTR:
|
||||
case LDNS_RR_TYPE_DNAME:
|
||||
/* type only has a single argument, the name */
|
||||
query_dname_tolower(datstart);
|
||||
return;
|
||||
case LDNS_RR_TYPE_MINFO:
|
||||
case LDNS_RR_TYPE_RP:
|
||||
case LDNS_RR_TYPE_SOA:
|
||||
/* two names after another */
|
||||
query_dname_tolower(datstart);
|
||||
query_dname_tolower(datstart +
|
||||
dname_valid(datstart, len-2));
|
||||
return;
|
||||
case LDNS_RR_TYPE_HINFO:
|
||||
/* lowercase text records */
|
||||
len -= 2;
|
||||
if(len < (size_t)datstart[0]+1)
|
||||
return;
|
||||
lowercase_text_field(datstart);
|
||||
len -= (size_t)datstart[0]+1; /* and skip the 1st */
|
||||
datstart += (size_t)datstart[0]+1;
|
||||
if(len < (size_t)datstart[0]+1)
|
||||
return;
|
||||
lowercase_text_field(datstart);
|
||||
return;
|
||||
case LDNS_RR_TYPE_RT:
|
||||
case LDNS_RR_TYPE_AFSDB:
|
||||
case LDNS_RR_TYPE_KX:
|
||||
case LDNS_RR_TYPE_MX:
|
||||
/* skip fixed part */
|
||||
if(len < 2+2+1) /* rdlen, skiplen, 1byteroot */
|
||||
return;
|
||||
datstart += 2;
|
||||
query_dname_tolower(datstart);
|
||||
return;
|
||||
case LDNS_RR_TYPE_SIG:
|
||||
case LDNS_RR_TYPE_RRSIG:
|
||||
/* skip fixed part */
|
||||
if(len < 2+18+1)
|
||||
return;
|
||||
datstart += 18;
|
||||
query_dname_tolower(datstart);
|
||||
return;
|
||||
case LDNS_RR_TYPE_PX:
|
||||
/* skip, then two names after another */
|
||||
if(len < 2+2+1)
|
||||
return;
|
||||
datstart += 2;
|
||||
query_dname_tolower(datstart);
|
||||
query_dname_tolower(datstart +
|
||||
dname_valid(datstart, len-2-2));
|
||||
return;
|
||||
case LDNS_RR_TYPE_NAPTR:
|
||||
if(len < 2+4)
|
||||
return;
|
||||
len -= 2+4;
|
||||
datstart += 4;
|
||||
if(len < (size_t)datstart[0]+1) /* skip text field */
|
||||
return;
|
||||
len -= (size_t)datstart[0]+1;
|
||||
datstart += (size_t)datstart[0]+1;
|
||||
if(len < (size_t)datstart[0]+1) /* skip text field */
|
||||
return;
|
||||
len -= (size_t)datstart[0]+1;
|
||||
datstart += (size_t)datstart[0]+1;
|
||||
if(len < (size_t)datstart[0]+1) /* skip text field */
|
||||
return;
|
||||
len -= (size_t)datstart[0]+1;
|
||||
datstart += (size_t)datstart[0]+1;
|
||||
if(len < 1) /* check name is at least 1 byte*/
|
||||
return;
|
||||
query_dname_tolower(datstart);
|
||||
return;
|
||||
case LDNS_RR_TYPE_SRV:
|
||||
/* skip fixed part */
|
||||
if(len < 2+6+1)
|
||||
return;
|
||||
datstart += 6;
|
||||
query_dname_tolower(datstart);
|
||||
return;
|
||||
/* A6 not supported */
|
||||
default:
|
||||
/* nothing to do for unknown types */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create canonical form of rrset in the scratch buffer.
|
||||
* @param buf: the buffer to use.
|
||||
* @param k: the rrset to insert.
|
||||
* @param sig: RRSIG rdata to include.
|
||||
* @param siglen: RRSIG rdata len excluding signature field, but inclusive
|
||||
* signer name length.
|
||||
* @return false on alloc error.
|
||||
*/
|
||||
static int
|
||||
rrset_canonical(ldns_buffer* buf, struct ub_packed_rrset_key* k,
|
||||
uint8_t* sig, size_t siglen)
|
||||
{
|
||||
struct packed_rrset_data* d = (struct packed_rrset_data*)k->entry.data;
|
||||
size_t i;
|
||||
uint8_t* can_owner = NULL;
|
||||
size_t can_owner_len = 0;
|
||||
/* sort RRs in place */
|
||||
canonical_sort(k);
|
||||
|
||||
ldns_buffer_clear(buf);
|
||||
ldns_buffer_write(buf, sig, siglen);
|
||||
query_dname_tolower(sig+18); /* canonicalize signer name */
|
||||
for(i=0; i<d->count; i++) {
|
||||
/* determine canonical owner name */
|
||||
if(can_owner)
|
||||
ldns_buffer_write(buf, can_owner, can_owner_len);
|
||||
else insert_can_owner(buf, k, sig, &can_owner,
|
||||
&can_owner_len);
|
||||
ldns_buffer_write(buf, &k->rk.type, 2);
|
||||
ldns_buffer_write(buf, &k->rk.rrset_class, 2);
|
||||
ldns_buffer_write(buf, sig+4, 4);
|
||||
ldns_buffer_write(buf, d->rr_data[i], d->rr_len[i]);
|
||||
canonicalize_rdata(buf, k, d->rr_len[i]);
|
||||
}
|
||||
ldns_buffer_flip(buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** check rrsig dates */
|
||||
static int
|
||||
check_dates(struct val_env* ve, uint8_t* expi_p, uint8_t* incep_p)
|
||||
{
|
||||
/* read out the dates */
|
||||
int32_t expi, incep, now;
|
||||
memmove(&expi, expi_p, sizeof(expi));
|
||||
memmove(&incep, incep_p, sizeof(incep));
|
||||
expi = ntohl(expi);
|
||||
incep = ntohl(incep);
|
||||
|
||||
/* get current date */
|
||||
if(ve->date_override)
|
||||
now = ve->date_override;
|
||||
else now = (int32_t)time(0);
|
||||
|
||||
/* check them */
|
||||
if(incep - expi > 0) {
|
||||
verbose(VERB_ALGO, "verify: inception after expiration, "
|
||||
"signature bad");
|
||||
return 0;
|
||||
}
|
||||
if(incep - now > 0) {
|
||||
verbose(VERB_ALGO, "verify: signature bad, current time is"
|
||||
" before inception date");
|
||||
return 0;
|
||||
}
|
||||
if(now - expi > 0) {
|
||||
verbose(VERB_ALGO, "verify: signature expired");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
enum sec_status
|
||||
dnskey_verify_rrset_sig(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
|
||||
size_t dnskey_idx, size_t sig_idx)
|
||||
{
|
||||
uint8_t* sig; /* rdata */
|
||||
size_t siglen;
|
||||
size_t rrnum = rrset_get_count(rrset);
|
||||
uint8_t* signer;
|
||||
size_t signer_len;
|
||||
uint8_t* sigblock; /* signature rdata field */
|
||||
size_t sigblock_len;
|
||||
uint16_t ktag;
|
||||
rrset_get_rdata(rrset, rrnum + sig_idx, &sig, &siglen);
|
||||
/* min length of rdatalen, fixed rrsig, root signer, 1 byte sig */
|
||||
if(siglen < 2+20) {
|
||||
verbose(VERB_ALGO, "verify: signature too short");
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
if(!(dnskey_get_flags(dnskey, dnskey_idx) & DNSKEY_BIT_ZSK)) {
|
||||
verbose(VERB_ALGO, "verify: dnskey without ZSK flag");
|
||||
return sec_status_bogus; /* signer name invalid */
|
||||
}
|
||||
|
||||
/* verify as many fields in rrsig as possible */
|
||||
signer = sig+2+18;
|
||||
signer_len = dname_valid(signer, siglen-2-18);
|
||||
if(!signer_len) {
|
||||
verbose(VERB_ALGO, "verify: malformed signer name");
|
||||
return sec_status_bogus; /* signer name invalid */
|
||||
}
|
||||
sigblock = signer+signer_len;
|
||||
if(siglen < 2+18+signer_len+1) {
|
||||
verbose(VERB_ALGO, "verify: too short, no signature data");
|
||||
return sec_status_bogus; /* sig rdf is < 1 byte */
|
||||
}
|
||||
sigblock_len = siglen - 2 - 18 - signer_len;
|
||||
|
||||
/* verify key dname == sig signer name */
|
||||
if(query_dname_compare(signer, dnskey->rk.dname) != 0) {
|
||||
verbose(VERB_ALGO, "verify: wrong key for rrsig");
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
/* verify covered type */
|
||||
/* memcmp works because type is in network format for rrset */
|
||||
if(memcmp(sig+2, &rrset->rk.type, 2) != 0) {
|
||||
verbose(VERB_ALGO, "verify: wrong type covered");
|
||||
return sec_status_bogus;
|
||||
}
|
||||
/* verify keytag and sig algo (possibly again) */
|
||||
if((int)sig[2] != dnskey_get_algo(dnskey, dnskey_idx)) {
|
||||
verbose(VERB_ALGO, "verify: wrong algorithm");
|
||||
return sec_status_bogus;
|
||||
}
|
||||
ktag = dnskey_calc_keytag(dnskey, dnskey_idx);
|
||||
if(memcmp(sig+16, &ktag, 2) != 0) {
|
||||
verbose(VERB_ALGO, "verify: wrong keytag");
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
/* verify labels is in a valid range */
|
||||
if((int)sig[3] > dname_signame_label_count(rrset->rk.dname)) {
|
||||
verbose(VERB_ALGO, "verify: labelcount out of range");
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
/* original ttl, always ok */
|
||||
|
||||
/* verify inception, expiration dates */
|
||||
if(!check_dates(ve, sig+8, sig+12)) {
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
/* create rrset canonical format in buffer, ready for signature */
|
||||
if(!rrset_canonical(env->scratch_buffer, rrset, sig+2,
|
||||
18 + signer_len)) {
|
||||
log_err("verify: failed due to alloc error");
|
||||
return sec_status_unchecked;
|
||||
}
|
||||
|
||||
/* verify */
|
||||
return sec_status_unchecked;
|
||||
|
|
|
|||
|
|
@ -122,6 +122,14 @@ int ds_get_key_algo(struct ub_packed_rrset_key* k, size_t idx);
|
|||
*/
|
||||
int dnskey_get_algo(struct ub_packed_rrset_key* k, size_t idx);
|
||||
|
||||
/**
|
||||
* Get DNSKEY RR flags
|
||||
* @param k: DNSKEY rrset.
|
||||
* @param idx: which DNSKEY RR.
|
||||
* @return flags or 0 if DNSKEY too short.
|
||||
*/
|
||||
uint16_t dnskey_get_flags(struct ub_packed_rrset_key* k, size_t idx);
|
||||
|
||||
/**
|
||||
* Verify rrset against dnskey rrset.
|
||||
* @param env: module environment, scratch space is used.
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@
|
|||
#include "util/log.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/region-allocator.h"
|
||||
#include "util/config_file.h"
|
||||
|
||||
/** apply config settings to validator */
|
||||
static int
|
||||
|
|
@ -72,6 +73,7 @@ val_apply_cfg(struct val_env* val_env, struct config_file* cfg)
|
|||
log_err("validator: error in trustanchors config");
|
||||
return 0;
|
||||
}
|
||||
val_env->date_override = cfg->val_date_override;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -65,6 +65,10 @@ struct val_env {
|
|||
/** key cache; these are validated keys. trusted keys only
|
||||
* end up here after being primed. */
|
||||
struct key_cache* kcache;
|
||||
|
||||
/** for debug testing a fixed validation date can be entered.
|
||||
* if 0, current time is used for rrsig validation */
|
||||
int32_t date_override;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue