Fixup trust anchor algorithm check.
git-svn-id: https://unbound.nlnetlabs.nl/svn/trunk@1532 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
db6002ee2a
commit
91b39120f4
@ -1,5 +1,9 @@
|
||||
18 March 2009: Wouter
|
||||
- Added tests, unknown algorithms become insecure. fallback works.
|
||||
- Fix for and test for unknown algorithms in a trust anchor
|
||||
definition. Trust anchors with no supported algos are ignored.
|
||||
This means a (higher)DS or DLV entry for them could succeed, and
|
||||
otherwise they are treated as insecure.
|
||||
|
||||
17 March 2009: Wouter
|
||||
- unit test for unsupported algorithm in anchor warning.
|
||||
|
150
testdata/val_unalgo_anchor.rpl
vendored
Normal file
150
testdata/val_unalgo_anchor.rpl
vendored
Normal file
@ -0,0 +1,150 @@
|
||||
; config options
|
||||
; The island of trust is at example.com
|
||||
server:
|
||||
trust-anchor: "example.com. 3600 IN DS 2854 208 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
|
||||
val-override-date: "20070916134226"
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test validator with unsupported algorithm trust anchor
|
||||
|
||||
; K.ROOT-SERVERS.NET.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 193.0.14.129
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
. IN NS
|
||||
SECTION ANSWER
|
||||
. IN NS K.ROOT-SERVERS.NET.
|
||||
SECTION ADDITIONAL
|
||||
K.ROOT-SERVERS.NET. IN A 193.0.14.129
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION AUTHORITY
|
||||
com. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; a.gtld-servers.net.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 192.5.6.30
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
com. IN NS
|
||||
SECTION ANSWER
|
||||
com. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.4
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN NS
|
||||
SECTION ANSWER
|
||||
example.com. IN NS ns.example.com.
|
||||
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
||||
ENTRY_END
|
||||
|
||||
; response to DNSKEY priming query
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN DNSKEY
|
||||
SECTION ANSWER
|
||||
example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
|
||||
example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
||||
ENTRY_END
|
||||
|
||||
; response to query of interest
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. IN A 10.20.30.40
|
||||
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. IN A 10.20.30.40
|
||||
www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
@ -823,35 +823,34 @@ anchors_assemble(struct val_anchors* anchors, struct trust_anchor* ta)
|
||||
/**
|
||||
* Check DS algos for support, warn if not.
|
||||
* @param ta: trust anchor
|
||||
* @return true if all anchors are supported.
|
||||
* @return number of DS anchors with unsupported algorithms.
|
||||
*/
|
||||
static int
|
||||
anchors_ds_is_supported(struct trust_anchor* ta)
|
||||
static size_t
|
||||
anchors_ds_unsupported(struct trust_anchor* ta)
|
||||
{
|
||||
size_t i;
|
||||
size_t i, num = 0;
|
||||
for(i=0; i<ta->numDS; i++) {
|
||||
if(!ds_digest_algo_is_supported(ta->ds_rrset, i))
|
||||
return 0;
|
||||
if(!ds_key_algo_is_supported(ta->ds_rrset, i))
|
||||
return 0;
|
||||
if(!ds_digest_algo_is_supported(ta->ds_rrset, i) ||
|
||||
!ds_key_algo_is_supported(ta->ds_rrset, i))
|
||||
num++;
|
||||
}
|
||||
return 1;
|
||||
return num;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check DNSKEY algos for support, warn if not.
|
||||
* @param ta: trust anchor
|
||||
* @return true if all anchors are supported.
|
||||
* @return number of DNSKEY anchors with unsupported algorithms.
|
||||
*/
|
||||
static int
|
||||
anchors_dnskey_is_supported(struct trust_anchor* ta)
|
||||
static size_t
|
||||
anchors_dnskey_unsupported(struct trust_anchor* ta)
|
||||
{
|
||||
size_t i;
|
||||
size_t i, num = 0;
|
||||
for(i=0; i<ta->numDNSKEY; i++) {
|
||||
if(!dnskey_algo_is_supported(ta->dnskey_rrset, i))
|
||||
return 0;
|
||||
num++;
|
||||
}
|
||||
return 1;
|
||||
return num;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -863,21 +862,35 @@ static int
|
||||
anchors_assemble_rrsets(struct val_anchors* anchors)
|
||||
{
|
||||
struct trust_anchor* ta;
|
||||
RBTREE_FOR(ta, struct trust_anchor*, anchors->tree) {
|
||||
struct trust_anchor* next;
|
||||
size_t nods, nokey;
|
||||
ta=(struct trust_anchor*)rbtree_first(anchors->tree);
|
||||
while((rbnode_t*)ta != RBTREE_NULL) {
|
||||
next = (struct trust_anchor*)rbtree_next(&ta->node);
|
||||
if(!anchors_assemble(anchors, ta)) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
if(!anchors_ds_is_supported(ta)) {
|
||||
nods = anchors_ds_unsupported(ta);
|
||||
nokey = anchors_dnskey_unsupported(ta);
|
||||
if(nods) {
|
||||
log_nametypeclass(0, "warning: unsupported "
|
||||
"algorithm for trust anchor",
|
||||
ta->name, LDNS_RR_TYPE_DS, ta->dclass);
|
||||
}
|
||||
if(!anchors_dnskey_is_supported(ta)) {
|
||||
if(nokey) {
|
||||
log_nametypeclass(0, "warning: unsupported "
|
||||
"algorithm for trust anchor",
|
||||
ta->name, LDNS_RR_TYPE_DNSKEY, ta->dclass);
|
||||
}
|
||||
if(nods == ta->numDS && nokey == ta->numDNSKEY) {
|
||||
char b[257];
|
||||
dname_str(ta->name, b);
|
||||
log_warn("trust anchor %s has no supported algorithms,"
|
||||
" the anchor is ignored", b);
|
||||
(void)rbtree_delete(anchors->tree, &ta->node);
|
||||
}
|
||||
ta = next;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -946,8 +959,9 @@ anchors_apply_cfg(struct val_anchors* anchors, struct config_file* cfg)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
init_parents(anchors);
|
||||
/* first assemble, since it may delete useless anchors */
|
||||
anchors_assemble_rrsets(anchors);
|
||||
init_parents(anchors);
|
||||
ldns_buffer_free(parsebuf);
|
||||
return 1;
|
||||
}
|
||||
|
@ -718,16 +718,15 @@ val_mark_indeterminate(struct reply_info* rep, struct val_anchors* anchors,
|
||||
}
|
||||
|
||||
void
|
||||
val_mark_insecure(struct reply_info* rep, struct key_entry_key* kkey,
|
||||
val_mark_insecure(struct reply_info* rep, uint8_t* kname,
|
||||
struct rrset_cache* r, struct module_env* env)
|
||||
{
|
||||
size_t i;
|
||||
struct packed_rrset_data* d;
|
||||
log_assert(key_entry_isnull(kkey));
|
||||
for(i=0; i<rep->rrset_count; i++) {
|
||||
d = (struct packed_rrset_data*)rep->rrsets[i]->entry.data;
|
||||
if(d->security == sec_status_unchecked &&
|
||||
dname_subdomain_c(rep->rrsets[i]->rk.dname, kkey->name)) {
|
||||
dname_subdomain_c(rep->rrsets[i]->rk.dname, kname)) {
|
||||
/* mark as insecure */
|
||||
d->security = sec_status_insecure;
|
||||
rrset_update_sec_status(r, rep->rrsets[i], *env->now);
|
||||
|
@ -240,12 +240,11 @@ void val_mark_indeterminate(struct reply_info* rep,
|
||||
* Mark all unchecked rrset entries below a NULL key entry as insecure.
|
||||
* Only security==unchecked rrsets are updated.
|
||||
* @param rep: the reply with rrsets.
|
||||
* @param kkey: key entry, key_entry_isnull() for it. A key entry that marks
|
||||
* the end of secure space into insecure space.
|
||||
* @param kname: end of secure space name.
|
||||
* @param r: rrset cache to store updated security status into.
|
||||
* @param env: module environment
|
||||
*/
|
||||
void val_mark_insecure(struct reply_info* rep, struct key_entry_key* kkey,
|
||||
void val_mark_insecure(struct reply_info* rep, uint8_t* kname,
|
||||
struct rrset_cache* r, struct module_env* env);
|
||||
|
||||
/**
|
||||
|
@ -1209,6 +1209,17 @@ processInit(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
else if(vq->key_entry == NULL || (vq->trust_anchor &&
|
||||
dname_strict_subdomain_c(vq->trust_anchor->name,
|
||||
vq->key_entry->name))) {
|
||||
/* trust anchor is an 'unsigned' trust anchor */
|
||||
if(vq->trust_anchor && vq->trust_anchor->numDS == 0 &&
|
||||
vq->trust_anchor->numDNSKEY == 0) {
|
||||
vq->chase_reply->security = sec_status_insecure;
|
||||
val_mark_insecure(vq->chase_reply,
|
||||
vq->trust_anchor->name,
|
||||
qstate->env->rrset_cache, qstate->env);
|
||||
/* go to finished state to cache this result */
|
||||
vq->state = VAL_FINISHED_STATE;
|
||||
return 1;
|
||||
}
|
||||
/* fire off a trust anchor priming query. */
|
||||
verbose(VERB_DETAIL, "prime trust anchor");
|
||||
if(!prime_trust_anchor(qstate, vq, id, vq->trust_anchor))
|
||||
@ -1222,7 +1233,7 @@ processInit(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
* However, we do set the status to INSECURE, since it is
|
||||
* essentially proven insecure. */
|
||||
vq->chase_reply->security = sec_status_insecure;
|
||||
val_mark_insecure(vq->chase_reply, vq->key_entry,
|
||||
val_mark_insecure(vq->chase_reply, vq->key_entry->name,
|
||||
qstate->env->rrset_cache, qstate->env);
|
||||
/* go to finished state to cache this result */
|
||||
vq->state = VAL_FINISHED_STATE;
|
||||
@ -1394,7 +1405,7 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
verbose(VERB_DETAIL, "Verified that %sresponse is INSECURE",
|
||||
vq->signer_name?"":"unsigned ");
|
||||
vq->chase_reply->security = sec_status_insecure;
|
||||
val_mark_insecure(vq->chase_reply, vq->key_entry,
|
||||
val_mark_insecure(vq->chase_reply, vq->key_entry->name,
|
||||
qstate->env->rrset_cache, qstate->env);
|
||||
return 1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user