diff --git a/testdata/val_anchor_nx_nosig.rpl b/testdata/val_anchor_nx_nosig.rpl index e0dc7d8ab..96065d9ce 100644 --- a/testdata/val_anchor_nx_nosig.rpl +++ b/testdata/val_anchor_nx_nosig.rpl @@ -87,6 +87,31 @@ 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 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +ns.example.com. IN A +SECTION ANSWER +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 + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +ns.example.com. IN AAAA +SECTION ANSWER +SECTION AUTHORITY +example.com. SOA ns.example.com. h.example.com. 2007090504 1800 1800 2419200 7200 +example.com. 3600 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. MCwCFC5uwIHSehZtetK2CMNXttSFUB0XAhROFDAgy/FaxR8zFXJzyPdpQG93Sw== ;{id = 2854} +ns.example.com. 3600 IN NSEC ns2.example.com. A RRSIG NSEC +ns.example.com. 3600 IN RRSIG NSEC 3 3 3600 20070926134150 20070829134150 2854 example.com. AIVgciU4SJJYLbVUMVgx+j7hqy9lBa75WTpRZWgNvtYJzB3u7mP1MvY= +ENTRY_END + ; response to DNSKEY priming query ENTRY_BEGIN MATCH opcode qtype qname @@ -201,17 +226,20 @@ ENTRY_END STEP 10 CHECK_ANSWER ENTRY_BEGIN MATCH all -REPLY QR RD RA DO NXDOMAIN +REPLY QR RD RA DO SERVFAIL SECTION QUESTION www.sub.example.com. IN A SECTION ANSWER SECTION AUTHORITY -example.com. SOA ns.example.com. h.example.com. 2007090504 1800 1800 2419200 7200 -example.com. 3600 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. MCwCFC5uwIHSehZtetK2CMNXttSFUB0XAhROFDAgy/FaxR8zFXJzyPdpQG93Sw== ;{id = 2854} -blub.example.com. NSEC znub.example.com. A MX RRSIG NSEC -blub.example.com. 3600 IN RRSIG NSEC 3 3 3600 20070926134150 20070829134150 2854 example.com. MCwCFCic/WwyMtdDE/84g8l0S0M8AOtnAhR88hQEp5cD5XQ3EmQ79RUuNTCgdg== ;{id = 2854} -example.com. NSEC blub.example.com. SOA NS MX DNSKEY RRSIG NSEC -example.com. 3600 IN RRSIG NSEC 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFFYX7iNIlT79gNFFlvnn44Ittm6HAhUAg7u0hZ4to87qyfkonZu2jVLW3xw= ;{id = 2854} +; the answer is bogus, because the parent does not have a secure denial +; of the trust island subdomain. The parent is signed, but the resolver +; does not have a trust anchor for the parent. +;example.com. SOA ns.example.com. h.example.com. 2007090504 1800 1800 2419200 7200 +;example.com. 3600 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. MCwCFC5uwIHSehZtetK2CMNXttSFUB0XAhROFDAgy/FaxR8zFXJzyPdpQG93Sw== ;{id = 2854} +;blub.example.com. NSEC znub.example.com. A MX RRSIG NSEC +;blub.example.com. 3600 IN RRSIG NSEC 3 3 3600 20070926134150 20070829134150 2854 example.com. MCwCFCic/WwyMtdDE/84g8l0S0M8AOtnAhR88hQEp5cD5XQ3EmQ79RUuNTCgdg== ;{id = 2854} +;example.com. NSEC blub.example.com. SOA NS MX DNSKEY RRSIG NSEC +;example.com. 3600 IN RRSIG NSEC 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFFYX7iNIlT79gNFFlvnn44Ittm6HAhUAg7u0hZ4to87qyfkonZu2jVLW3xw= ;{id = 2854} SECTION ADDITIONAL ENTRY_END diff --git a/validator/validator.c b/validator/validator.c index 4958a2242..be4e7c3ed 100644 --- a/validator/validator.c +++ b/validator/validator.c @@ -2007,13 +2007,15 @@ processInit(struct module_qstate* qstate, struct val_qstate* vq, anchor = anchors_lookup(qstate->env->anchors, lookup_name, lookup_len, vq->qchase.qclass); if(!anchor) { /* unsigned parent denies anchor*/ - verbose(VERB_QUERY, "unsigned parent zone denies" - " trust anchor, indeterminate"); - vq->chase_reply->security = sec_status_indeterminate; - update_reason_bogus(vq->chase_reply, LDNS_EDE_DNSSEC_INDETERMINATE); + verbose(VERB_ALGO, "unsigned parent zone denies" + " trust anchor, thus bogus"); + errinf_ede(qstate, "unsigned parent zone denies trust anchor, thus bogus", LDNS_EDE_DNSSEC_BOGUS); + vq->chase_reply->security = sec_status_bogus; + update_reason_bogus(vq->chase_reply, LDNS_EDE_DNSSEC_BOGUS); vq->state = VAL_FINISHED_STATE; return 1; } + vq->parent_denial_must_be_secure = 1; verbose(VERB_ALGO, "trust anchor NXDOMAIN by signed parent"); } else if(subtype == VAL_CLASS_POSITIVE && qstate->qinfo.qtype == LDNS_RR_TYPE_DNSKEY && @@ -2538,6 +2540,15 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq, enum val_classification subtype = val_classify_response( qstate->query_flags, &qstate->qinfo, &vq->qchase, vq->orig_msg->rep, vq->rrset_skip); + if(vq->parent_denial_must_be_secure) { + if(vq->chase_reply->security != sec_status_secure && + vq->chase_reply->security != sec_status_bogus) { + verbose(VERB_ALGO, "parent denial of trust island subdomain is not secure, thus bogus"); + vq->chase_reply->security = sec_status_bogus; + update_reason_bogus(vq->chase_reply, LDNS_EDE_DNSSEC_BOGUS); + errinf_ede(qstate, "parent denial of trust island subdomain is not secure, thus bogus", LDNS_EDE_DNSSEC_BOGUS); + } + } /* store overall validation result in orig_msg */ if(vq->rrset_skip == 0) { diff --git a/validator/validator.h b/validator/validator.h index f7bc3550a..ab88fe124 100644 --- a/validator/validator.h +++ b/validator/validator.h @@ -244,6 +244,10 @@ struct val_qstate { int num_nsec_attempts; /** The nsec attempts have been exceeded. */ int num_nsec_attempts_exceeded; + + /** if validation must be secure, (else bogus) for NXDOMAIN + * from signed parent to (removed) trust anchor subdomain. */ + int parent_denial_must_be_secure; }; /**