]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
Review for #759:
authorGeorge Thessalonikefs <george@nlnetlabs.nl>
Wed, 19 Jul 2023 12:52:20 +0000 (14:52 +0200)
committerGeorge Thessalonikefs <george@nlnetlabs.nl>
Wed, 19 Jul 2023 13:20:44 +0000 (15:20 +0200)
- Keep EDE information for keys close to key creation.
- Fix inconsistencies between reply and cached EDEs.
- Incorporate EDE caching checks in EDE tests.
- Fix some EDE cases where missing DNSKEY was wrongly reported.

40 files changed:
services/mesh.c
testdata/autotrust_init_fail.rpl
testdata/autotrust_init_failsig.rpl
testdata/autotrust_probefail.rpl
testdata/autotrust_probefailsig.rpl
testdata/black_ds_entry.rpl
testdata/black_key_entry.rpl
testdata/black_prime_entry.rpl
testdata/ede_cache_snoop_not_auth.rpl [moved from testdata/ede_cache_snoop_noth_auth.rpl with 100% similarity]
testdata/ede_caching.rpl [deleted file]
testdata/nsid_bogus.rpl
testdata/root_key_sentinel.rpl
testdata/val_cnametocloser_nosig.rpl
testdata/val_cnametonodata_nonsec.rpl
testdata/val_cnametoposnowc.rpl
testdata/val_deleg_nons.rpl
testdata/val_dnamewc.rpl
testdata/val_ds_cname.rpl
testdata/val_faildnskey.rpl
testdata/val_nodata_failsig.rpl
testdata/val_nodata_failwc.rpl
testdata/val_nokeyprime.rpl
testdata/val_nsec3_b1_nameerror_nowc.rpl
testdata/val_nsec3_b2_nodata_nons.rpl
testdata/val_nsec3_entnodata_optout_badopt.rpl
testdata/val_nsec3_nods_badsig.rpl
testdata/val_nx_failwc.rpl
testdata/val_nx_overreach.rpl
testdata/val_secds_nosig.rpl
testdata/val_ta_algo_missing.rpl
util/module.c
validator/val_kcache.c
validator/val_kcache.h
validator/val_kentry.c
validator/val_kentry.h
validator/val_nsec.c
validator/val_nsec.h
validator/val_sigcrypt.c
validator/val_utils.c
validator/validator.c

index 6148b0bc612f8912efd5d8d0c699ba2245a5db1d..c46505efd83b6e60715e5bc1cb622cf6c5bc7bc3 100644 (file)
@@ -1234,36 +1234,34 @@ mesh_is_rpz_respip_tcponly_action(struct mesh_state const* m)
 }
 
 static inline int
-mesh_is_udp(struct mesh_reply const* r) {
+mesh_is_udp(struct mesh_reply const* r)
+{
        return r->query_reply.c->type == comm_udp;
 }
 
 static inline void
 mesh_find_and_attach_ede_and_reason(struct mesh_state* m,
-       struct reply_info* rep, struct mesh_reply* r) {
-       char *reason = m->s.env->cfg->val_log_level >= 2
-               ? errinf_to_str_bogus(&m->s) : NULL;
-
-       /* During validation the EDE code can be received via two
+       struct reply_info* rep, struct mesh_reply* r)
+{
+       /* OLD note:
+        * During validation the EDE code can be received via two
         * code paths. One code path fills the reply_info EDE, and
         * the other fills it in the errinf_strlist. These paths
         * intersect at some points, but where is opaque due to
         * the complexity of the validator. At the time of writing
         * we make the choice to prefer the EDE from errinf_strlist
         * but a compelling reason to do otherwise is just as valid
+        * NEW note:
+        * The compelling reason is that with caching support, the value
+        * in the * reply_info is cached.
+        * The reason members of the reply_info struct should be
+        * updated as they are already cached. No reason to
+        * try and find the EDE information in errinf anymore.
         */
-       sldns_ede_code reason_bogus = errinf_to_reason_bogus(&m->s);
-       if ((reason_bogus == LDNS_EDE_DNSSEC_BOGUS &&
-               rep->reason_bogus != LDNS_EDE_NONE) ||
-               reason_bogus == LDNS_EDE_NONE) {
-                       reason_bogus = rep->reason_bogus;
-       }
-
-       if(reason_bogus != LDNS_EDE_NONE) {
+       if(rep->reason_bogus != LDNS_EDE_NONE) {
                edns_opt_list_append_ede(&r->edns.opt_list_out,
-                       m->s.region, reason_bogus, reason);
+                       m->s.region, rep->reason_bogus, rep->reason_bogus_str);
        }
-       free(reason);
 }
 
 /**
index 1f3fed9570a2323c863c0bf691629100b35bb959..00703026d274de486fb809de50206a92695d1e1e 100644 (file)
@@ -5,6 +5,7 @@ server:
        fake-sha1: yes
        trust-anchor-signaling: no
        ede: yes
+       access-control: 127.0.0.0/8 allow_snoop
 
 stub-zone:
        name: "."
@@ -159,6 +160,23 @@ www.example.com. IN A
 SECTION ANSWER
 ENTRY_END
 
+; Redo the query without RD to check EDE caching.
+STEP 21 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 22 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=9
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
 ; The autotrust anchor was probed due to the query.
 
 STEP 30 CHECK_AUTOTRUST example.com
index 7f6a14d833e5d3ff04cbcdeed6beab73e0c03ae7..29a8d11d193dfbb11a326165035679210fac2e34 100644 (file)
@@ -6,6 +6,7 @@ server:
        fake-sha1: yes
        trust-anchor-signaling: no
        ede: yes
+       access-control: 127.0.0.0/8 allow_snoop
 
 stub-zone:
        name: "."
@@ -147,6 +148,23 @@ www.example.com. IN A
 SECTION ANSWER
 ENTRY_END
 
+; Redo the query without RD to check EDE caching.
+STEP 21 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 22 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=6
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
 ; The autotrust anchor was probed due to the query.
 
 STEP 30 CHECK_AUTOTRUST example.com
index e22cbf71ff96366f59f29c0879034e12f32a78bd..992d9629df13519b1df2df9be8b973d24ab9ad53 100644 (file)
@@ -5,6 +5,7 @@ server:
        fake-sha1: yes
        trust-anchor-signaling: no
        ede: yes
+       access-control: 127.0.0.0/8 allow_snoop
 
 stub-zone:
        name: "."
@@ -164,4 +165,21 @@ www.example.com. IN A
 SECTION ANSWER
 ENTRY_END
 
+; Redo the query without RD to check EDE caching.
+STEP 40 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 50 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=9
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
 SCENARIO_END
index 7d486ffbc39714e3040c40e90a3a394adee73262..3988add01acf994cbfe247fce474c373c3a1501a 100644 (file)
@@ -5,6 +5,7 @@ server:
        fake-sha1: yes
        trust-anchor-signaling: no
        ede: yes
+       access-control: 127.0.0.0/8 allow_snoop
 
 stub-zone:
        name: "."
@@ -164,4 +165,21 @@ www.example.com. IN A
 SECTION ANSWER
 ENTRY_END
 
+; Redo the query without RD to check EDE caching.
+STEP 40 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 50 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=6
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
 SCENARIO_END
index 168dc236d20318658e055f0cd2c41c9156e10cf0..f2e7a2a992419311e0ca86ae9a3147fd1531c70b 100644 (file)
@@ -7,6 +7,7 @@ server:
        fake-sha1: yes
        trust-anchor-signaling: no
        ede: yes
+       access-control: 127.0.0.0/8 allow_snoop
 
 stub-zone:
        name: "."
@@ -586,6 +587,23 @@ www.sub.example.com. IN A
 SECTION ANSWER
 ENTRY_END
 
+; Redo the query without RD to check EDE caching.
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+www.sub.example.com. IN A
+ENTRY_END
+
+STEP 30 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=7
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
 ; no more outgoing traffic possible.
 STEP 110 QUERY
 ENTRY_BEGIN
@@ -603,6 +621,23 @@ ftp.sub.example.com. IN A
 SECTION ANSWER
 ENTRY_END
 
+; Redo the query without RD to check EDE caching.
+STEP 121 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+ftp.sub.example.com. IN A
+ENTRY_END
+
+STEP 122 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=7
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+ftp.sub.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
 ; wait for timeout seconds.
 STEP 130 TIME_PASSES ELAPSE 901
 
index cd2b0bfbe55707b86006542b470562257d02cac8..c66e1dbb13ad9f4926c23cf6980ae3bf1de3cb78 100644 (file)
@@ -7,6 +7,7 @@ server:
        fake-sha1: yes
        trust-anchor-signaling: no
        ede: yes
+       access-control: 127.0.0.0/8 allow_snoop
 
 stub-zone:
        name: "."
@@ -568,6 +569,23 @@ www.sub.example.com. IN A
 SECTION ANSWER
 ENTRY_END
 
+; Redo the query without RD to check EDE caching.
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+www.sub.example.com. IN A
+ENTRY_END
+
+STEP 30 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=7
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
 ; no more outgoing traffic possible.
 STEP 110 QUERY
 ENTRY_BEGIN
@@ -585,6 +603,23 @@ ftp.sub.example.com. IN A
 SECTION ANSWER
 ENTRY_END
 
+; Redo the query without RD to check EDE caching.
+STEP 121 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+ftp.sub.example.com. IN A
+ENTRY_END
+
+STEP 122 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=7
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+ftp.sub.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
 ; wait for timeout seconds.
 STEP 130 TIME_PASSES ELAPSE 901
 
index e635ed9cc10bd8c66f8b4daafb5b881589875df8..1acd7d7c12e7553136f83a9eb131e373ecc28712 100644 (file)
@@ -8,6 +8,7 @@ server:
        fake-sha1: yes
        trust-anchor-signaling: no
        ede: yes
+       access-control: 127.0.0.0/8 allow_snoop
 
 stub-zone:
        name: "."
@@ -292,6 +293,22 @@ SECTION QUESTION
 www.example.com. IN A
 ENTRY_END
 
+; Redo the query without RD to check EDE caching.
+STEP 11 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 12 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=7
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
 STEP 100 TIME_PASSES ELAPSE 10
 
 ; second query should not result in going to the network.
@@ -311,5 +328,21 @@ SECTION QUESTION
 ftp.example.com. IN A
 ENTRY_END
 
+; Redo the query without RD to check EDE caching.
+STEP 121 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+ftp.example.com. IN A
+ENTRY_END
+
+STEP 122 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=7
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+ftp.example.com. IN A
+ENTRY_END
+
 
 SCENARIO_END
diff --git a/testdata/ede_caching.rpl b/testdata/ede_caching.rpl
deleted file mode 100644 (file)
index 63bcac2..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-; @TODO decide if we want to keep this, or change the original test(s)
-; This test is a copy of autotrust_probefail, where the query is executed twide
-
-
-; config options
-server:
-       target-fetch-policy: "0 0 0 0 0"
-       log-time-ascii: yes
-       fake-sha1: yes
-       trust-anchor-signaling: no
-       ede: yes
-
-stub-zone:
-       name: "."
-       stub-addr: 193.0.14.129         # K.ROOT-SERVERS.NET.
-AUTOTRUST_FILE example.com
-; autotrust trust anchor file
-;;id: example.com. 1
-;;last_queried: 1258962400 ;;Mon Nov 23 08:46:40 2009
-;;last_success: 1258962400 ;;Mon Nov 23 08:46:40 2009
-;;next_probe_time: 1258967360 ;;Mon Nov 23 10:09:20 2009
-;;query_failed: 0
-;;query_interval: 5400
-;;retry_time: 3600
-example.com.    10800   IN      DNSKEY  257 3 5 AwEAAas/cAhCFXvBUgTSNZCvQp0pLx1dY+7rXR0hH4/3EUgWmsmbYUpI1qD0xhwKD/oYGEwAm291fyWJ9c0oVxXDEK8= ;{id = 16486 (ksk), size = 512b} ;;state=2 [  VALID  ] ;;count=0 ;;lastchange=1258962400 ;;Mon Nov 23 08:46:40 2009
-example.com.   10800   IN      DNSKEY  257 3 5 AwEAAc3Z5DQDJpH4oPdNtC4BUQHk50XMD+dHr4r8psHmivIa83hxR5CRgCtd9sENCW9Ae8OIO19xw9t/RPaEAqQa+OE= ;{id = 55582 (ksk), size = 512b} ;;state=2 [  VALID  ] ;;count=0 ;;lastchange=1258962400 ;;Mon Nov 23 08:46:40 2009
-AUTOTRUST_END
-CONFIG_END
-
-SCENARIO_BEGIN Test autotrust with probe failure
-
-; K-ROOT
-RANGE_BEGIN 0 100
-       ADDRESS 193.0.14.129
-ENTRY_BEGIN
-MATCH opcode qname qtype
-ADJUST copy_id copy_query
-REPLY QR AA
-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 subdomain
-ADJUST copy_id copy_query
-REPLY QR
-SECTION QUESTION
-com. IN NS
-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 subdomain
-ADJUST copy_id copy_query
-REPLY QR
-SECTION QUESTION
-example.com. IN NS
-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 qname qtype
-ADJUST copy_id
-REPLY QR AA SERVFAIL
-SECTION QUESTION
-ns.example.com. IN AAAA
-SECTION ANSWER
-ENTRY_END
-
-ENTRY_BEGIN
-MATCH opcode qname qtype
-ADJUST copy_id
-REPLY QR AA
-SECTION QUESTION
-ns.example.com. IN A
-SECTION ANSWER
-ns.example.com.        3600    IN      A       1.2.3.4
-ns.example.com.        3600    IN      RRSIG   A 5 3 3600 20090924111500 20090821111500 30899 example.com. JsXbS18oyc0zkVaOWGSFdIQuOsZKflT0GraT9afDPoWLCgH4ApF7jNgfJV7Pqy1sTBRajME5IUAhpANwGBuW4A== ;{id = 30899}
-SECTION AUTHORITY
-example.com.   3600    IN      NS      ns.example.com.
-example.com.   3600    IN      RRSIG   NS 5 2 3600 20090924111500 20090821111500 30899 example.com. J5wxRq0jgwQL6yy530kvo9cHqNAUHV8IF4dvaYZL0bNraO2Oe6dVXqlJl4+cxNHI2TMsstwFPr2Zz8tv6Az2mQ== ;{id = 30899}
-SECTION ADDITIONAL
-ENTRY_END
-
-ENTRY_BEGIN
-MATCH opcode qname qtype
-ADJUST copy_id
-REPLY QR AA SERVFAIL
-SECTION QUESTION
-example.com. IN DNSKEY
-SECTION ANSWER
-
-; revoked keys
-example.com.    10800   IN      DNSKEY  385 3 5 AwEAAc3Z5DQDJpH4oPdNtC4BUQHk50XMD+dHr4r8psHmivIa83hxR5CRgCtd9sENCW9Ae8OIO19xw9t/RPaEAqQa+OE= ;{id = 55710 (ksk), size = 512b}
-example.com.   10800   IN      DNSKEY  385 3 5 AwEAAas/cAhCFXvBUgTSNZCvQp0pLx1dY+7rXR0hH4/3EUgWmsmbYUpI1qD0xhwKD/oYGEwAm291fyWJ9c0oVxXDEK8= ;{id = 16614 (ksk), size = 512b}
-; signatures
-example.com.   10800   IN      RRSIG   DNSKEY 5 2 10800 20091124111500 20091018111500 55710 example.com. zOSlB1iwtlP2lum1RK0WoDQrMVj0JKwk2E5Mu1okzV38hAx3Xm9IGMK6WrNkVVLmx4OkhYmdPVA95jVsFpwLMw== ;{id = 55710}
-example.com.   10800   IN      RRSIG   DNSKEY 5 2 10800 20091124111500 20091018111500 16614 example.com. qP49cCYP3lvNnLBYty/JxAwHqBIGjpup5zQ7qpjPnaZpBb/TlpOhY17LBZrqD86VvBbEVz5tkxC9UrCy85ePDQ== ;{id = 16614}
-
-ENTRY_END
-
-ENTRY_BEGIN
-MATCH opcode subdomain
-ADJUST copy_id copy_query
-REPLY QR
-SECTION QUESTION
-www.example.com. IN A
-SECTION ANSWER
-www.example.com. IN A 10.20.30.40
-ENTRY_END
-RANGE_END
-
-RANGE_END
-
-; set date/time to Mon Nov 23 09:46:40 2009
-STEP 5 TIME_PASSES EVAL ${1258962400 + 7200}
-STEP 6 TRAFFIC   ; do the probe
-STEP 7 ASSIGN t0 = ${time}
-STEP 8 ASSIGN probe0 = ${range 3200 ${timeout} 3600}
-STEP 9 ASSIGN tp = ${1258962400}
-
-; the auto probing should have been done now.
-STEP 11 CHECK_AUTOTRUST example.com
-FILE_BEGIN
-; autotrust trust anchor file
-;;id: example.com. 1
-;;last_queried: 1258962400 ;;Mon Nov 23 08:46:40 2009
-;;last_success: 1258962400 ;;Mon Nov 23 08:46:40 2009
-;;next_probe_time: 1258967360 ;;Mon Nov 23 10:09:20 2009
-;;query_failed: 0
-;;query_interval: 5400
-;;retry_time: 3600
-example.com.    10800   IN      DNSKEY  257 3 5 AwEAAas/cAhCFXvBUgTSNZCvQp0pLx1dY+7rXR0hH4/3EUgWmsmbYUpI1qD0xhwKD/oYGEwAm291fyWJ9c0oVxXDEK8= ;{id = 16486 (ksk), size = 512b} ;;state=2 [  VALID  ] ;;count=0 ;;lastchange=1258962400 ;;Mon Nov 23 08:46:40 2009
-example.com.   10800   IN      DNSKEY  257 3 5 AwEAAc3Z5DQDJpH4oPdNtC4BUQHk50XMD+dHr4r8psHmivIa83hxR5CRgCtd9sENCW9Ae8OIO19xw9t/RPaEAqQa+OE= ;{id = 55582 (ksk), size = 512b} ;;state=2 [  VALID  ] ;;count=0 ;;lastchange=1258962400 ;;Mon Nov 23 08:46:40 2009
-FILE_END
-
-STEP 20 QUERY
-ENTRY_BEGIN
-REPLY RD DO
-SECTION QUESTION
-www.example.com. IN A
-ENTRY_END
-
-STEP 30 CHECK_ANSWER
-ENTRY_BEGIN
-MATCH all ede=9
-REPLY QR RD RA DO SERVFAIL
-SECTION QUESTION
-www.example.com. IN A
-SECTION ANSWER
-ENTRY_END
-
-STEP 40 QUERY
-ENTRY_BEGIN
-REPLY RD DO
-SECTION QUESTION
-www.example.com. IN A
-ENTRY_END
-
-STEP 50 CHECK_ANSWER
-ENTRY_BEGIN
-MATCH all ede=9
-REPLY QR RD RA DO SERVFAIL
-SECTION QUESTION
-www.example.com. IN A
-SECTION ANSWER
-ENTRY_END
-
-SCENARIO_END
index b92563cf2d1e6c1c8eae9a470b182320b7036a35..9a80e1d7503b7d5a0b6c4e58c64a899df6cf4051 100644 (file)
@@ -10,6 +10,7 @@ server:
        minimal-responses: no
        nsid: "ascii_hopsa kidee"
        ede: yes
+       access-control: 127.0.0.0/8 allow_snoop
 
 stub-zone:
        name: "."
@@ -175,4 +176,33 @@ SECTION ADDITIONAL
        HEX_EDNSDATA_END
 ENTRY_END
 
+; Redo the query without RD to check EDE caching.
+STEP 11 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+www.example.com. IN A
+SECTION ADDITIONAL
+       HEX_EDNSDATA_BEGIN
+               00 03 ; Opcode NSID (3)
+               00 00 ; Length 0
+       HEX_EDNSDATA_END
+ENTRY_END
+
+STEP 12 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=9
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION ADDITIONAL
+       HEX_EDNSDATA_BEGIN
+               00 03             ; Opcode NSID (3)
+               00 0b             ; Length 11
+               68 6F 70 73 61 20 ; "hopsa "
+               6B 69 64 65 65    ; "kidee"
+       HEX_EDNSDATA_END
+ENTRY_END
+
 SCENARIO_END
index 39bd9685c293314c079d2c072930b13f1cbb72c3..e368bc52185e67b116eb681d57e79a1ecc9e13f2 100644 (file)
@@ -5,6 +5,7 @@ server:
        target-fetch-policy: "0 0 0 0 0"
        trust-anchor-signaling: no
        ede: yes
+       access-control: 127.0.0.0/8 allow_snoop
 
 stub-zone:
        name: "."
@@ -145,6 +146,22 @@ SECTION QUESTION
 root-key-sentinel-not-ta-19036.        IN      A
 ENTRY_END
 
+; Redo the query without RD to check EDE caching.
+STEP 23 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+root-key-sentinel-not-ta-19036.        IN      A
+ENTRY_END
+
+STEP 24 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=6
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+root-key-sentinel-not-ta-19036.        IN      A
+ENTRY_END
+
 STEP 30 QUERY
 ENTRY_BEGIN
 REPLY RD DO
@@ -161,6 +178,22 @@ SECTION QUESTION
 root-key-sentinel-is-ta-20326. IN      A
 ENTRY_END
 
+; Redo the query without RD to check EDE caching.
+STEP 34 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+root-key-sentinel-is-ta-20326. IN      A
+ENTRY_END
+
+STEP 35 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=6
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+root-key-sentinel-is-ta-20326. IN      A
+ENTRY_END
+
 STEP 40 QUERY
 ENTRY_BEGIN
 REPLY RD DO
index 6a0552ec540432aeec16142376f25f58268e5f7a..eca05b1aaf904dcdcf92a795f8a2a3dd169424ce 100644 (file)
@@ -6,6 +6,7 @@ server:
        fake-sha1: yes
        trust-anchor-signaling: no
        ede: yes
+       access-control: 127.0.0.0/8 allow_snoop
 
 forward-zone:
        name: "."
@@ -89,11 +90,27 @@ ENTRY_END
 ; recursion happens here.
 STEP 10 CHECK_ANSWER
 ENTRY_BEGIN
-MATCH all ede=9
+MATCH all ede=10
 REPLY QR RD RA DO SERVFAIL
 SECTION QUESTION
 www.example.com. IN AAAA
 SECTION ANSWER
 ENTRY_END
 
+; Redo the query without RD to check EDE caching.
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+www.example.com. IN AAAA
+ENTRY_END
+STEP 21 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=10
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+www.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
 SCENARIO_END
index cf743321b9291ec6e8103e9b211e8d488a6fa567..8f3927575ecb4c420657d2075da24308a744042b 100644 (file)
@@ -9,6 +9,7 @@ server:
        fake-sha1: yes
        trust-anchor-signaling: no
        ede: yes
+       access-control: 127.0.0.0/8 allow_snoop
 
 stub-zone:
        name: "."
@@ -268,4 +269,21 @@ www.example.com. IN A
 SECTION ANSWER
 ENTRY_END
 
+; Redo the query without RD to check EDE caching.
+STEP 11 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 12 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=10
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
 SCENARIO_END
index 2975bd8d2a036c08533d3ce57198d0fbe25a59d5..1ba57633c1464f076acb0ada43e49acef058981b 100644 (file)
@@ -9,6 +9,7 @@ server:
        fake-sha1: yes
        trust-anchor-signaling: no
        ede: yes
+       access-control: 127.0.0.0/8 allow_snoop
 
 stub-zone:
        name: "."
@@ -261,4 +262,21 @@ www.example.com. IN A
 SECTION ANSWER
 ENTRY_END
 
+; Redo the query without RD to check EDE caching.
+STEP 11 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 12 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=6
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
 SCENARIO_END
index 82348d95b7f9624f25eb037ab07f84d13597eb95..aac87eab731602c3d71fb419d94eef49ec38350c 100644 (file)
@@ -8,6 +8,7 @@ server:
        fake-sha1: yes
        trust-anchor-signaling: no
        ede: yes
+       access-control: 127.0.0.0/8 allow_snoop
 
 stub-zone:
        name: "."
@@ -269,4 +270,21 @@ foo.www.example.com. IN A
 SECTION ANSWER
 ENTRY_END
 
+; Redo the query without RD to check EDE caching.
+STEP 11 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+foo.www.example.com. IN A
+ENTRY_END
+
+STEP 12 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=10
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+foo.www.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
 SCENARIO_END
index 1a0e41ecff0ba1a33ad0f0eec9eb3679fbe10877..ee72f6a1fa1b5322345d3427d9367b1328d8e56e 100644 (file)
@@ -9,6 +9,7 @@ server:
        fake-sha1: yes
        trust-anchor-signaling: no
        ede: yes
+       access-control: 127.0.0.0/8 allow_snoop
 
 stub-zone:
        name: "."
@@ -264,4 +265,21 @@ www.sub.example.com. IN A
 SECTION ANSWER
 ENTRY_END
 
+; Redo the query without RD to check EDE caching.
+STEP 11 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+www.sub.example.com. IN A
+ENTRY_END
+
+STEP 12 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=6
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
 SCENARIO_END
index 1703601e52f66967197f500a331d697782d34c35..a49c53538ebe08314aad3350d549e60480b59879 100644 (file)
@@ -8,6 +8,7 @@ server:
        fake-sha1: yes
        trust-anchor-signaling: no
        ede: yes
+       access-control: 127.0.0.0/8 allow_snoop
 
 stub-zone:
        name: "."
@@ -204,4 +205,20 @@ SECTION QUESTION
 www.example.com. IN A
 ENTRY_END
 
+; Redo the query without RD to check EDE caching.
+STEP 11 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 12 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=10
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
 SCENARIO_END
index f45080a0b2f9c9f7bb1ff1f6c22aa94891fc8e72..cc1cc9eeed0fc6284c445ca744ede1f7412c4fd0 100644 (file)
@@ -8,6 +8,7 @@ server:
        fake-sha1: yes
        trust-anchor-signaling: no
        ede: yes
+       access-control: 127.0.0.0/8 allow_snoop
 
 stub-zone:
        name: "."
@@ -171,4 +172,21 @@ www.example.com. IN A
 SECTION ANSWER
 ENTRY_END
 
+; Redo the query without RD to check EDE caching.
+STEP 11 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 12 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=9
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
 SCENARIO_END
index 0c4426bc10549b23fa6a1a92469ff3f67c0b93cb..16b46d4fd33b28d2cfe903ba38038c513e0ab2d5 100644 (file)
@@ -8,6 +8,7 @@ server:
        fake-sha1: yes
        trust-anchor-signaling: no
        ede: yes
+       access-control: 127.0.0.0/8 allow_snoop
 
 stub-zone:
        name: "."
@@ -162,4 +163,21 @@ www.example.com. IN A
 SECTION ANSWER
 ENTRY_END
 
+; Redo the query without RD to check EDE caching.
+STEP 11 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 12 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=6
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
 SCENARIO_END
index 3aa8212c893219750506c4019cdca97de9cc8f46..7ac61fa2bddb45a03456e68a0fe362c751c80914 100644 (file)
@@ -8,6 +8,7 @@ server:
        fake-sha1: yes
        trust-anchor-signaling: no
        ede: yes
+       access-control: 127.0.0.0/8 allow_snoop
 
 stub-zone:
        name: "nsecwc.nlnetlabs.nl"
@@ -17,8 +18,8 @@ CONFIG_END
 
 SCENARIO_BEGIN Test validator with nodata response with wildcard expanded NSEC record, original NSEC owner does not provide proof for QNAME. CVE-2017-15105 test.
 
- ; ns.example.com.                                                                
-RANGE_BEGIN 0 100                                                                
+ ; ns.example.com.
+RANGE_BEGIN 0 100
        ADDRESS 185.49.140.60
 
 ; response to DNSKEY priming query
@@ -69,4 +70,21 @@ _25._tcp.mail.nsecwc.nlnetlabs.nl. IN   TLSA
 SECTION ANSWER
 ENTRY_END
 
+; Redo the query without RD to check EDE caching.
+STEP 11 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+_25._tcp.mail.nsecwc.nlnetlabs.nl. IN   TLSA
+ENTRY_END
+
+STEP 12 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=6
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+_25._tcp.mail.nsecwc.nlnetlabs.nl. IN   TLSA
+SECTION ANSWER
+ENTRY_END
+
 SCENARIO_END
index 5d37274207994a6466b44fd81155a5d0eea9f964..b7646d34ca8bb6d306d78b729b983314bf2d181a 100644 (file)
@@ -7,6 +7,7 @@ server:
        fake-sha1: yes
        trust-anchor-signaling: no
        ede: yes
+       access-control: 127.0.0.0/8 allow_snoop
 
 stub-zone:
        name: "."
@@ -161,4 +162,21 @@ www.example.com. IN A
 SECTION ANSWER
 ENTRY_END
 
+; Redo the query without RD to check EDE caching.
+STEP 11 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 12 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=9
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
 SCENARIO_END
index 0ff135af6bbaa83246ad749d74a9b9438cfbcab3..9445fec08907d20b3fe815bb9c2e112edbadc2dd 100644 (file)
@@ -7,6 +7,7 @@ server:
        fake-sha1: yes
        trust-anchor-signaling: no
        ede: yes
+       access-control: 127.0.0.0/8 allow_snoop
 
 stub-zone:
        name: "."
@@ -140,12 +141,24 @@ SECTION QUESTION
 a.c.x.w.example. IN A
 SECTION ANSWER
 SECTION AUTHORITY
-; example.       SOA     ns1.example. bugs.x.w.example. 1 3600 300 ( 3600000 3600 )
-; example.        RRSIG   SOA 7 1 3600 20150420235959 20051021000000 ( 40430 example.  Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8i q4ZLlYWfUUbbAS41pG+68z81q1xhkYAcEyHd VI2LmKusbZsT0Q== )
-; 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. NSEC3 1 1 12 aabbccdd ( 2t7b4g4vsa5smi47k61mv5bv1a22bojr MX DNSKEY NS SOA NSEC3PARAM RRSIG )
-; 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. RRSIG   NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example.  OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKL IBHYH6blRxK9rC0bMJPwQ4mLIuw85H2EY762 BOCXJZMnpuwhpA== )
-; b4um86eghhds6nea196smvmlo4ors995.example. NSEC3 1 1 12 aabbccdd ( gjeqe526plbf1g8mklp59enfd789njgi MX RRSIG )
-; b4um86eghhds6nea196smvmlo4ors995.example. RRSIG   NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example.  ZkPG3M32lmoHM6pa3D6gZFGB/rhL//Bs3Omh 5u4m/CUiwtblEVOaAKKZd7S959OeiX43aLX3 pOv0TSTyiTxIZg== )
+ENTRY_END
+
+; Redo the query without RD to check EDE caching.
+STEP 11 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+a.c.x.w.example. IN A
+ENTRY_END
+
+STEP 12 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=6
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+a.c.x.w.example. IN A
+SECTION ANSWER
+SECTION AUTHORITY
 ENTRY_END
 
 SCENARIO_END
index 7faaafac60df8dfcb4beb3994e85f08fee55a44f..7dd06a392fa16f195ab46d1b491e74c9934679a5 100644 (file)
@@ -6,6 +6,7 @@ server:
        fake-sha1: yes
        trust-anchor-signaling: no
        ede: yes
+       access-control: 127.0.0.0/8 allow_snoop
 
 stub-zone:
        name: "."
@@ -138,4 +139,21 @@ ns1.example.        IN MX
 SECTION ANSWER
 ENTRY_END
 
+; Redo the query without RD to check EDE caching.
+STEP 11 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+ns1.example.        IN MX
+ENTRY_END
+
+STEP 12 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=12
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+ns1.example.        IN MX
+SECTION ANSWER
+ENTRY_END
+
 SCENARIO_END
index b672bd6e6cc231bfa63f7a0228926f35f1b29a7e..c7e5a50068bee05c0fe6f42375b0250e9bc24f7a 100644 (file)
@@ -7,6 +7,7 @@ server:
        fake-sha1: yes
        trust-anchor-signaling: no
        ede: yes
+       access-control: 127.0.0.0/8 allow_snoop
 
 stub-zone:
        name: "."
@@ -194,4 +195,21 @@ ent.example.com. IN A
 SECTION ANSWER
 ENTRY_END
 
+; Redo the query without RD to check EDE caching.
+STEP 11 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+ent.example.com. IN A
+ENTRY_END
+
+STEP 12 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=6
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+ent.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
 SCENARIO_END
index 79290d659ae762b3444b6c312dfe34b9dc942887..d99470f344fc613afe9ebf025a3c2de0d02da8ad 100644 (file)
@@ -8,6 +8,7 @@ server:
        fake-sha1: yes
        trust-anchor-signaling: no
        ede: yes
+       access-control: 127.0.0.0/8 allow_snoop
 
 stub-zone:
        name: "."
@@ -234,4 +235,20 @@ www.sub.example.com. IN A
 SECTION ANSWER
 ENTRY_END
 
+STEP 11 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+www.sub.example.com. IN A
+ENTRY_END
+
+STEP 12 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=7
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
 SCENARIO_END
index 645a6b4c9728f8a442a24c814f79a8dd94c0f03f..765b34456d966644f9e68eaec33e926b535d138d 100644 (file)
@@ -8,6 +8,7 @@ server:
        fake-sha1: yes
        trust-anchor-signaling: no
        ede: yes
+       access-control: 127.0.0.0/8 allow_snoop
 
 stub-zone:
        name: "nsecwc.nlnetlabs.nl"
@@ -67,4 +68,21 @@ a.nsecwc.nlnetlabs.nl. IN   TXT
 SECTION ANSWER
 ENTRY_END
 
+; Redo the query without RD to check EDE caching.
+STEP 11 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+a.nsecwc.nlnetlabs.nl. IN   TXT
+ENTRY_END
+
+STEP 12 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=6
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+a.nsecwc.nlnetlabs.nl. IN   TXT
+SECTION ANSWER
+ENTRY_END
+
 SCENARIO_END
index e5046bc1a445da4bfac1091db0c21a2d6293d65e..28089e5f361cf2bf88898f36d1676c69ddb3d8a1 100644 (file)
@@ -8,6 +8,7 @@ server:
        fake-sha1: yes
        trust-anchor-signaling: no
        ede: yes
+       access-control: 127.0.0.0/8 allow_snoop
 
 stub-zone:
        name: "."
@@ -162,4 +163,21 @@ www.example.com. IN A
 SECTION ANSWER
 ENTRY_END
 
+; Redo the query without RD to check EDE caching.
+STEP 11 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 12 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=6
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
 SCENARIO_END
index 69f83a393c1055bd1f115c73da50214f09609ec0..ec768799d7f9b821fdcc6eeea14b78c0c75a62d6 100644 (file)
@@ -7,6 +7,7 @@ server:
        fake-sha1: yes
        trust-anchor-signaling: no
        ede: yes
+       access-control: 127.0.0.0/8 allow_snoop
 
 stub-zone:
        name: "."
@@ -230,4 +231,19 @@ SECTION QUESTION
 www.sub.example.com. IN A
 ENTRY_END
 
+STEP 11 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+www.sub.example.com. IN A
+ENTRY_END
+
+STEP 12 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=10
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+www.sub.example.com. IN A
+ENTRY_END
+
 SCENARIO_END
index 9efb24266c05b877bb681d70e5e30dc3f6529b10..537af2cb3e6b0f810ca749688f049a46ef11db31 100644 (file)
@@ -11,6 +11,7 @@ server:
        fake-sha1: yes
        trust-anchor-signaling: no
        ede: yes
+       access-control: 127.0.0.0/8 allow_snoop
 
 stub-zone:
        name: "."
@@ -166,11 +167,27 @@ ENTRY_END
 ; recursion happens here.
 STEP 10 CHECK_ANSWER
 ENTRY_BEGIN
-MATCH all ede=9
+MATCH all ede=6
 REPLY QR RD RA DO SERVFAIL
 SECTION QUESTION
 www.example.com. IN A
 SECTION ANSWER
 ENTRY_END
 
+STEP 11 QUERY
+ENTRY_BEGIN
+REPLY DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 12 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ede=6
+REPLY QR RA DO SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
 SCENARIO_END
index 6698f94971b813f28bb864f1bd89680452095e96..773dab853d2fc8ae6baf545654d7ddc79f33bab9 100644 (file)
@@ -84,8 +84,10 @@ void errinf_ede(struct module_qstate* qstate,
        const char* str, sldns_ede_code reason_bogus)
 {
        struct errinf_strlist* p;
-       if((qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail) || !str)
+       if(!str || (qstate->env->cfg->val_log_level < 2 &&
+               !qstate->env->cfg->log_servfail)) {
                return;
+       }
        p = (struct errinf_strlist*)regional_alloc(qstate->region, sizeof(*p));
        if(!p) {
                log_err("malloc failure in validator-error-info string");
@@ -152,15 +154,19 @@ char* errinf_to_str_bogus(struct module_qstate* qstate)
        return p;
 }
 
+/* Try to find the latest (most specific) dnssec failure */
 sldns_ede_code errinf_to_reason_bogus(struct module_qstate* qstate)
 {
        struct errinf_strlist* s;
+       sldns_ede_code ede = LDNS_EDE_NONE;
        for(s=qstate->errinf; s; s=s->next) {
-               if (s->reason_bogus != LDNS_EDE_NONE) {
-                       return s->reason_bogus;
-               }
+               if(s->reason_bogus == LDNS_EDE_NONE) continue;
+               if(ede != LDNS_EDE_NONE
+                       && ede != LDNS_EDE_DNSSEC_BOGUS
+                       && s->reason_bogus == LDNS_EDE_DNSSEC_BOGUS) continue;
+               ede = s->reason_bogus;
        }
-       return LDNS_EDE_NONE;
+       return ede;
 }
 
 char* errinf_to_str_servfail(struct module_qstate* qstate)
index c190085b56ffc0b11c04667f90ae03b5de276ffa..f5d49d24f2db4017eb87efb6f15f8dd643c6b942 100644 (file)
@@ -81,17 +81,11 @@ key_cache_delete(struct key_cache* kcache)
 
 void 
 key_cache_insert(struct key_cache* kcache, struct key_entry_key* kkey,
-       struct module_qstate* qstate)
+       int copy_reason)
 {
-       struct key_entry_key* k = key_entry_copy(kkey);
+       struct key_entry_key* k = key_entry_copy(kkey, copy_reason);
        if(!k)
                return;
-       if(key_entry_isbad(k) && qstate->errinf &&
-               qstate->env->cfg->val_log_level >= 2) {
-               /* on malloc failure there is simply no reason string */
-               key_entry_set_reason(k, errinf_to_str_bogus(qstate));
-               key_entry_set_reason_bogus(k, errinf_to_reason_bogus(qstate));
-       }
        key_entry_hash(k);
        slabhash_insert(kcache->slab, k->entry.hash, &k->entry, 
                k->entry.data, NULL);
index 76c9dd094d1a3482ff65df966a52f414d2eae52d..df8de0999b3fdf1f44109827f5e4a882a448193f 100644 (file)
@@ -76,10 +76,10 @@ void key_cache_delete(struct key_cache* kcache);
  * @param kcache: the key cache.
  * @param kkey: key entry key, assumed malloced in a region, is copied
  *     to perform update or insertion. Its data pointer is also copied.
- * @param qstate: store errinf reason in case its bad.
+ * @param copy_reason: if the reason string needs to be copied (allocated).
  */
 void key_cache_insert(struct key_cache* kcache, struct key_entry_key* kkey,
-       struct module_qstate* qstate);
+       int copy_reason);
 
 /**
  * Remove an entry from the key cache.
index a47feba61a9ff3c4f6a7e181ec1150ae06b5aef0..85f026402fa3fd8cbde9328a41dd173f88780576 100644 (file)
@@ -152,7 +152,7 @@ key_entry_copy_toregion(struct key_entry_key* kkey, struct regional* region)
 }
 
 struct key_entry_key* 
-key_entry_copy(struct key_entry_key* kkey)
+key_entry_copy(struct key_entry_key* kkey, int copy_reason)
 {
        struct key_entry_key* newk;
        if(!kkey)
@@ -190,7 +190,7 @@ key_entry_copy(struct key_entry_key* kkey)
                        }
                        packed_rrset_ptr_fixup(newd->rrset_data);
                }
-               if(d->reason) {
+               if(copy_reason && d->reason && *d->reason != 0) {
                        newd->reason = strdup(d->reason);
                        if(!newd->reason) {
                                free(newd->rrset_data);
@@ -199,6 +199,8 @@ key_entry_copy(struct key_entry_key* kkey)
                                free(newk);
                                return NULL;
                        }
+               } else {
+                       newd->reason = NULL;
                }
                if(d->algo) {
                        newd->algo = (uint8_t*)strdup((char*)d->algo);
@@ -237,22 +239,6 @@ key_entry_isbad(struct key_entry_key* kkey)
        return (int)(d->isbad);
 }
 
-void
-key_entry_set_reason(struct key_entry_key* kkey, char* reason)
-{
-       struct key_entry_data* d = (struct key_entry_data*)kkey->entry.data;
-       d->reason = reason;
-}
-
-void
-key_entry_set_reason_bogus(struct key_entry_key* kkey, sldns_ede_code ede)
-{
-       struct key_entry_data* d = (struct key_entry_data*)kkey->entry.data;
-       if (ede != LDNS_EDE_NONE) { /* reason_bogus init is LDNS_EDE_NONE already */
-               d->reason_bogus = ede;
-       }
-}
-
 char*
 key_entry_get_reason(struct key_entry_key* kkey)
 {
@@ -294,6 +280,7 @@ key_entry_setup(struct regional* region,
 struct key_entry_key* 
 key_entry_create_null(struct regional* region,
        uint8_t* name, size_t namelen, uint16_t dclass, time_t ttl,
+       sldns_ede_code reason_bogus, const char* reason,
        time_t now)
 {
        struct key_entry_key* k;
@@ -302,8 +289,10 @@ key_entry_create_null(struct regional* region,
                return NULL;
        d->ttl = now + ttl;
        d->isbad = 0;
-       d->reason = NULL;
-       d->reason_bogus = LDNS_EDE_NONE;
+       d->reason = (!reason || *reason == 0)
+               ?NULL :(char*)regional_strdup(region, reason);
+               /* On allocation error we don't store the reason string */
+       d->reason_bogus = reason_bogus;
        d->rrset_type = LDNS_RR_TYPE_DNSKEY;
        d->rrset_data = NULL;
        d->algo = NULL;
@@ -313,7 +302,9 @@ key_entry_create_null(struct regional* region,
 struct key_entry_key* 
 key_entry_create_rrset(struct regional* region,
        uint8_t* name, size_t namelen, uint16_t dclass,
-       struct ub_packed_rrset_key* rrset, uint8_t* sigalg, time_t now)
+       struct ub_packed_rrset_key* rrset, uint8_t* sigalg,
+       sldns_ede_code reason_bogus, const char* reason,
+       time_t now)
 {
        struct key_entry_key* k;
        struct key_entry_data* d;
@@ -323,8 +314,10 @@ key_entry_create_rrset(struct regional* region,
                return NULL;
        d->ttl = rd->ttl + now;
        d->isbad = 0;
-       d->reason = NULL;
-       d->reason_bogus = LDNS_EDE_NONE;
+       d->reason = (!reason || *reason == 0)
+               ?NULL :(char*)regional_strdup(region, reason);
+               /* On allocation error we don't store the reason string */
+       d->reason_bogus = reason_bogus;
        d->rrset_type = ntohs(rrset->rk.type);
        d->rrset_data = (struct packed_rrset_data*)regional_alloc_init(region,
                rd, packed_rrset_sizeof(rd));
@@ -341,7 +334,8 @@ key_entry_create_rrset(struct regional* region,
 
 struct key_entry_key* 
 key_entry_create_bad(struct regional* region,
-       uint8_t* name, size_t namelen, uint16_t dclass, time_t ttl, 
+       uint8_t* name, size_t namelen, uint16_t dclass, time_t ttl,
+       sldns_ede_code reason_bogus, const char* reason,
        time_t now)
 {
        struct key_entry_key* k;
@@ -350,8 +344,10 @@ key_entry_create_bad(struct regional* region,
                return NULL;
        d->ttl = now + ttl;
        d->isbad = 1;
-       d->reason = NULL;
-       d->reason_bogus = LDNS_EDE_NONE;
+       d->reason = (!reason || *reason == 0)
+               ?NULL :(char*)regional_strdup(region, reason);
+               /* On allocation error we don't store the reason string */
+       d->reason_bogus = reason_bogus;
        d->rrset_type = LDNS_RR_TYPE_DNSKEY;
        d->rrset_data = NULL;
        d->algo = NULL;
index ded45beaa71d66d5367db61db7b7b76696c178d9..ca9f0dabceb26792f6df7f252cf2c89368a1ed2f 100644 (file)
@@ -120,9 +120,11 @@ struct key_entry_key* key_entry_copy_toregion(struct key_entry_key* kkey,
 /**
  * Copy a key entry, malloced.
  * @param kkey: the key entry key (and data pointer) to copy.
+ * @param copy_reason: if the reason string needs to be copied (allocated).
  * @return newly allocated entry or NULL on a failure to allocate memory.
  */
-struct key_entry_key* key_entry_copy(struct key_entry_key* kkey);
+struct key_entry_key* key_entry_copy(struct key_entry_key* kkey,
+       int copy_reason);
 
 /**
  * See if this is a null entry. Does not do locking.
@@ -145,23 +147,6 @@ int key_entry_isgood(struct key_entry_key* kkey);
  */
 int key_entry_isbad(struct key_entry_key* kkey);
 
-/**
- * Set reason why a key is bad.
- * @param kkey: bad key.
- * @param reason: string to attach, you must allocate it.
- *    Not safe to call twice unless you deallocate it yourself.
- */
-void key_entry_set_reason(struct key_entry_key* kkey, char* reason);
-
-/**
- * Set the EDE (RFC8914) code why the key is bad, if it
- * exists (so not LDNS_EDE_NONE).
- * @param kkey: bad key.
- * @param ede: EDE code to attach to this key.
- */
-void key_entry_set_reason_bogus(struct key_entry_key* kkey, sldns_ede_code ede);
-
-
 /**
  * Get reason why a key is bad.
  * @param kkey: bad key
@@ -184,11 +169,14 @@ sldns_ede_code key_entry_get_reason_bogus(struct key_entry_key* kkey);
  * @param namelen: length of name
  * @param dclass: class of key entry. (host order);
  * @param ttl: what ttl should the key have. relative.
+ * @param reason_bogus: accompanying EDE code.
+ * @param reason: accompanying NULL-terminated EDE string (or NULL).
  * @param now: current time (added to ttl).
  * @return new key entry or NULL on alloc failure
  */
 struct key_entry_key* key_entry_create_null(struct regional* region,
-       uint8_t* name, size_t namelen, uint16_t dclass, time_t ttl, 
+       uint8_t* name, size_t namelen, uint16_t dclass, time_t ttl,
+       sldns_ede_code reason_bogus, const char* reason,
        time_t now);
 
 /**
@@ -199,12 +187,16 @@ struct key_entry_key* key_entry_create_null(struct regional* region,
  * @param dclass: class of key entry. (host order);
  * @param rrset: data for key entry. This is copied to the region.
  * @param sigalg: signalled algorithm list (or NULL).
+ * @param reason_bogus: accompanying EDE code (usually LDNS_EDE_NONE).
+ * @param reason: accompanying NULL-terminated EDE string (or NULL).
  * @param now: current time (added to ttl of rrset)
  * @return new key entry or NULL on alloc failure
  */
 struct key_entry_key* key_entry_create_rrset(struct regional* region,
-        uint8_t* name, size_t namelen, uint16_t dclass, 
-       struct ub_packed_rrset_key* rrset, uint8_t* sigalg, time_t now);
+       uint8_t* name, size_t namelen, uint16_t dclass,
+       struct ub_packed_rrset_key* rrset, uint8_t* sigalg,
+       sldns_ede_code reason_bogus, const char* reason,
+       time_t now);
 
 /**
  * Create a bad entry, in the given region.
@@ -213,11 +205,14 @@ struct key_entry_key* key_entry_create_rrset(struct regional* region,
  * @param namelen: length of name
  * @param dclass: class of key entry. (host order);
  * @param ttl: what ttl should the key have. relative.
+ * @param reason_bogus: accompanying EDE code.
+ * @param reason: accompanying NULL-terminated EDE string (or NULL).
  * @param now: current time (added to ttl).
  * @return new key entry or NULL on alloc failure
  */
 struct key_entry_key* key_entry_create_bad(struct regional* region,
        uint8_t* name, size_t namelen, uint16_t dclass, time_t ttl,
+       sldns_ede_code reason_bogus, const char* reason,
        time_t now);
 
 /**
index 876bfab6dbbd93b37591899a129086985ccfe128..17c90d83f59430edf4ce76a4dd07bff5e66f4588 100644 (file)
@@ -174,9 +174,10 @@ val_nsec_proves_no_ds(struct ub_packed_rrset_key* nsec,
 
 /** check security status from cache or verify rrset, returns true if secure */
 static int
-nsec_verify_rrset(struct module_env* env, struct val_env* ve, 
-       struct ub_packed_rrset_key* nsec, struct key_entry_key* kkey, 
-       char** reason, struct module_qstate* qstate)
+nsec_verify_rrset(struct module_env* env, struct val_env* ve,
+       struct ub_packed_rrset_key* nsec, struct key_entry_key* kkey,
+       char** reason, sldns_ede_code* reason_bogus,
+       struct module_qstate* qstate)
 {
        struct packed_rrset_data* d = (struct packed_rrset_data*)
                nsec->entry.data;
@@ -187,7 +188,7 @@ nsec_verify_rrset(struct module_env* env, struct val_env* ve,
        if(d->security == sec_status_secure)
                return 1;
        d->security = val_verify_rrset_entry(env, ve, nsec, kkey, reason,
-               NULL, LDNS_SECTION_AUTHORITY, qstate);
+               reason_bogus, LDNS_SECTION_AUTHORITY, qstate);
        if(d->security == sec_status_secure) {
                rrset_update_sec_status(env->rrset_cache, nsec, *env->now);
                return 1;
@@ -199,7 +200,7 @@ enum sec_status
 val_nsec_prove_nodata_dsreply(struct module_env* env, struct val_env* ve, 
        struct query_info* qinfo, struct reply_info* rep, 
        struct key_entry_key* kkey, time_t* proof_ttl, char** reason,
-       struct module_qstate* qstate)
+       sldns_ede_code* reason_bogus, struct module_qstate* qstate)
 {
        struct ub_packed_rrset_key* nsec = reply_find_rrset_section_ns(
                rep, qinfo->qname, qinfo->qname_len, LDNS_RR_TYPE_NSEC, 
@@ -216,7 +217,8 @@ val_nsec_prove_nodata_dsreply(struct module_env* env, struct val_env* ve,
         * 1) this is a delegation point and there is no DS
         * 2) this is not a delegation point */
        if(nsec) {
-               if(!nsec_verify_rrset(env, ve, nsec, kkey, reason, qstate)) {
+               if(!nsec_verify_rrset(env, ve, nsec, kkey, reason,
+                       reason_bogus, qstate)) {
                        verbose(VERB_ALGO, "NSEC RRset for the "
                                "referral did not verify.");
                        return sec_status_bogus;
@@ -225,6 +227,7 @@ val_nsec_prove_nodata_dsreply(struct module_env* env, struct val_env* ve,
                if(sec == sec_status_bogus) {
                        /* something was wrong. */
                        *reason = "NSEC does not prove absence of DS";
+                       *reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
                        return sec;
                } else if(sec == sec_status_insecure) {
                        /* this wasn't a delegation point. */
@@ -246,9 +249,11 @@ val_nsec_prove_nodata_dsreply(struct module_env* env, struct val_env* ve,
                if(rep->rrsets[i]->rk.type != htons(LDNS_RR_TYPE_NSEC))
                        continue;
                if(!nsec_verify_rrset(env, ve, rep->rrsets[i], kkey, reason,
-                       qstate)) {
+                       reason_bogus, qstate)) {
                        verbose(VERB_ALGO, "NSEC for empty non-terminal "
                                "did not verify.");
+                       *reason = "NSEC for empty non-terminal "
+                               "did not verify.";
                        return sec_status_bogus;
                }
                if(nsec_proves_nodata(rep->rrsets[i], qinfo, &wc)) {
index 7117809d60ae3ab7bbcfa75530524bf06b91ed21..81844c908e548fd0d1de6e5229ac74d51e5d6acf 100644 (file)
@@ -44,6 +44,7 @@
 #ifndef VALIDATOR_VAL_NSEC_H
 #define VALIDATOR_VAL_NSEC_H
 #include "util/data/packed_rrset.h"
+#include "sldns/rrdef.h"
 struct val_env;
 struct module_env;
 struct module_qstate;
@@ -65,6 +66,7 @@ struct key_entry_key;
  * @param kkey: key entry to use for verification of signatures.
  * @param proof_ttl: if secure, the TTL of how long this proof lasts.
  * @param reason: string explaining why bogus.
+ * @param reason_bogus: relevant EDE code for validation failure.
  * @param qstate: qstate with region.
  * @return security status.
  *     SECURE: proved absence of DS.
@@ -75,7 +77,8 @@ struct key_entry_key;
 enum sec_status val_nsec_prove_nodata_dsreply(struct module_env* env,
        struct val_env* ve, struct query_info* qinfo, 
        struct reply_info* rep, struct key_entry_key* kkey,
-       time_t* proof_ttl, char** reason, struct module_qstate* qstate);
+       time_t* proof_ttl, char** reason, sldns_ede_code* reason_bogus,
+       struct module_qstate* qstate);
 
 /** 
  * nsec typemap check, takes an NSEC-type bitmap as argument, checks for type.
index 5ab21e20e7356f2514e1c5a6371e8329759f6ee4..0ecd05f1391104a481523120b971807eb5fb9afb 100644 (file)
@@ -718,9 +718,9 @@ dnskey_verify_rrset(struct module_env* env, struct val_env* ve,
        }
        verbose(VERB_ALGO, "rrset failed to verify: all signatures are bogus");
        if(!numchecked) {
-               *reason = "signature missing";
+               *reason = "signatures bogus";
                if(reason_bogus)
-                       *reason_bogus = LDNS_EDE_RRSIGS_MISSING;
+                       *reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
        } else if(numchecked == numindeterminate) {
                verbose(VERB_ALGO, "rrset failed to verify due to algorithm "
                        "refusal by cryptolib");
index e2319ee2399d98074ef0e7cf6a42ec2f7d014bac..8b388882b82a6acac93aa684cfb270f15cf21f6e 100644 (file)
@@ -587,16 +587,18 @@ val_verify_new_DNSKEYs(struct regional* region, struct module_env* env,
                return key_entry_create_rrset(region, 
                        ds_rrset->rk.dname, ds_rrset->rk.dname_len,
                        ntohs(ds_rrset->rk.rrset_class), dnskey_rrset,
-                       downprot?sigalg:NULL, *env->now);
+                       downprot?sigalg:NULL, LDNS_EDE_NONE, NULL,
+                       *env->now);
        } else if(sec == sec_status_insecure) {
                return key_entry_create_null(region, ds_rrset->rk.dname,
-                       ds_rrset->rk.dname_len, 
+                       ds_rrset->rk.dname_len,
                        ntohs(ds_rrset->rk.rrset_class),
-                       rrset_get_ttl(ds_rrset), *env->now);
+                       rrset_get_ttl(ds_rrset), *reason_bogus, *reason,
+                       *env->now);
        }
        return key_entry_create_bad(region, ds_rrset->rk.dname,
                ds_rrset->rk.dname_len, ntohs(ds_rrset->rk.rrset_class),
-               BOGUS_KEY_TTL, *env->now);
+               BOGUS_KEY_TTL, *reason_bogus, *reason, *env->now);
 }
 
 enum sec_status
@@ -694,7 +696,7 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
                has_useful_ta = 1;
 
                sec = dnskey_verify_rrset(env, ve, dnskey_rrset,
-                       ta_dnskey, i, reason, NULL, LDNS_SECTION_ANSWER, qstate);
+                       ta_dnskey, i, reason, reason_bogus, LDNS_SECTION_ANSWER, qstate);
                if(sec == sec_status_secure) {
                        if(!sigalg || algo_needs_set_secure(&needs,
                                (uint8_t)dnskey_get_algo(ta_dnskey, i))) {
@@ -743,16 +745,17 @@ val_verify_new_DNSKEYs_with_ta(struct regional* region, struct module_env* env,
                return key_entry_create_rrset(region,
                        dnskey_rrset->rk.dname, dnskey_rrset->rk.dname_len,
                        ntohs(dnskey_rrset->rk.rrset_class), dnskey_rrset,
-                       downprot?sigalg:NULL, *env->now);
+                       downprot?sigalg:NULL, LDNS_EDE_NONE, NULL, *env->now);
        } else if(sec == sec_status_insecure) {
                return key_entry_create_null(region, dnskey_rrset->rk.dname,
                        dnskey_rrset->rk.dname_len,
                        ntohs(dnskey_rrset->rk.rrset_class),
-                       rrset_get_ttl(dnskey_rrset), *env->now);
+                       rrset_get_ttl(dnskey_rrset), *reason_bogus, *reason,
+                       *env->now);
        }
        return key_entry_create_bad(region, dnskey_rrset->rk.dname,
                dnskey_rrset->rk.dname_len, ntohs(dnskey_rrset->rk.rrset_class),
-               BOGUS_KEY_TTL, *env->now);
+               BOGUS_KEY_TTL, *reason_bogus, *reason, *env->now);
 }
 
 int
index 18e4de07223c9f11c3be259043ba9d715bd3b51e..9de9d54db27c9f7c974506897fe64a0d398fd87f 100644 (file)
@@ -70,16 +70,16 @@ static void process_ds_response(struct module_qstate* qstate,
        struct query_info* qinfo, struct sock_list* origin);
 
 
-/* Updates the suplied EDE (RFC8914) code selectively so we don't loose
- * a more specific code
- */
+/* Updates the suplied EDE (RFC8914) code selectively so we don't lose
+ * a more specific code */
 static void
 update_reason_bogus(struct reply_info* rep, sldns_ede_code reason_bogus)
 {
-       if (rep->reason_bogus == LDNS_EDE_DNSSEC_BOGUS ||
-               rep->reason_bogus == LDNS_EDE_NONE) {
-               rep->reason_bogus = reason_bogus;
-       }
+       if(reason_bogus == LDNS_EDE_NONE) return;
+       if(reason_bogus == LDNS_EDE_DNSSEC_BOGUS
+               && rep->reason_bogus != LDNS_EDE_NONE
+               && rep->reason_bogus != LDNS_EDE_DNSSEC_BOGUS) return;
+       rep->reason_bogus = reason_bogus;
 }
 
 
@@ -1672,20 +1672,13 @@ processInit(struct module_qstate* qstate, struct val_qstate* vq,
                vq->state = VAL_FINISHED_STATE;
                return 1;
        } else if(key_entry_isbad(vq->key_entry)) {
-               sldns_ede_code ede = LDNS_EDE_DNSSEC_BOGUS;
-
-               /* the key could have a more spefic EDE than just bogus */
-               if(key_entry_get_reason_bogus(vq->key_entry) != LDNS_EDE_NONE) {
-                       ede = key_entry_get_reason_bogus(vq->key_entry);
-               }
-
+               /* Bad keys should have the relevant EDE code and text */
+               sldns_ede_code ede = key_entry_get_reason_bogus(vq->key_entry);
                /* key is bad, chain is bad, reply is bogus */
                errinf_dname(qstate, "key for validation", vq->key_entry->name);
                errinf_ede(qstate, "is marked as invalid", ede);
-               if(key_entry_get_reason(vq->key_entry)) {
-                       errinf(qstate, "because of a previous");
-                       errinf(qstate, key_entry_get_reason(vq->key_entry));
-               }
+               errinf(qstate, "because of a previous");
+               errinf(qstate, key_entry_get_reason(vq->key_entry));
 
                /* no retries, stop bothering the authority until timeout */
                vq->restart_count = ve->max_restart;
@@ -1888,7 +1881,8 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
                vq->chase_reply->security = sec_status_insecure;
                val_mark_insecure(vq->chase_reply, vq->key_entry->name, 
                        qstate->env->rrset_cache, qstate->env);
-               key_cache_insert(ve->kcache, vq->key_entry, qstate);
+               key_cache_insert(ve->kcache, vq->key_entry,
+                       qstate->env->cfg->val_log_level >= 2);
                return 1;
        }
 
@@ -1897,12 +1891,13 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
                        "of trust to keys for", vq->key_entry->name,
                        LDNS_RR_TYPE_DNSKEY, vq->key_entry->key_class);
                vq->chase_reply->security = sec_status_bogus;
-
-               update_reason_bogus(vq->chase_reply, LDNS_EDE_DNSKEY_MISSING);
+               update_reason_bogus(vq->chase_reply,
+                       key_entry_get_reason_bogus(vq->key_entry));
                errinf_ede(qstate, "while building chain of trust",
-                       LDNS_EDE_DNSKEY_MISSING);
+                       key_entry_get_reason_bogus(vq->key_entry));
                if(vq->restart_count >= ve->max_restart)
-                       key_cache_insert(ve->kcache, vq->key_entry, qstate);
+                       key_cache_insert(ve->kcache, vq->key_entry,
+                               qstate->env->cfg->val_log_level >= 2);
                return 1;
        }
 
@@ -2156,7 +2151,7 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq,
                                        size_t err_str_len = strlen(err_str);
                                        log_info("%s", err_str);
                                        /* allocate space and store the error
-                                        * string; */
+                                        * string */
                                        vq->orig_msg->rep->reason_bogus_str = regional_alloc(
                                                qstate->region,
                                                sizeof(char) * (err_str_len+1));
@@ -2206,6 +2201,8 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq,
                }
        }
 
+       /* Update rep->reason_bogus as it is the one being cached */
+       update_reason_bogus(vq->orig_msg->rep, errinf_to_reason_bogus(qstate));
        /* store results in cache */
        if(qstate->query_flags&BIT_RD) {
                /* if secure, this will override cache anyway, no need
@@ -2381,13 +2378,17 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
                log_nametypeclass(VERB_OPS, "failed to prime trust anchor -- "
                        "could not fetch DNSKEY rrset", 
                        ta->name, LDNS_RR_TYPE_DNSKEY, ta->dclass);
+               reason_bogus = LDNS_EDE_DNSKEY_MISSING;
+               reason = "no DNSKEY rrset";
                if(qstate->env->cfg->harden_dnssec_stripped) {
-                       errinf_ede(qstate, "no DNSKEY rrset", LDNS_EDE_DNSKEY_MISSING);
+                       errinf_ede(qstate, reason, reason_bogus);
                        kkey = key_entry_create_bad(qstate->region, ta->name,
                                ta->namelen, ta->dclass, BOGUS_KEY_TTL,
+                               reason_bogus, reason,
                                *qstate->env->now);
                } else  kkey = key_entry_create_null(qstate->region, ta->name,
                                ta->namelen, ta->dclass, NULL_KEY_TTL,
+                               reason_bogus, reason,
                                *qstate->env->now);
                if(!kkey) {
                        log_err("out of memory: allocate fail prime key");
@@ -2420,9 +2421,11 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
                        errinf_ede(qstate, reason, reason_bogus);
                        kkey = key_entry_create_bad(qstate->region, ta->name,
                                ta->namelen, ta->dclass, BOGUS_KEY_TTL,
+                               reason_bogus, reason,
                                *qstate->env->now);
                } else  kkey = key_entry_create_null(qstate->region, ta->name,
                                ta->namelen, ta->dclass, NULL_KEY_TTL,
+                               reason_bogus, reason,
                                *qstate->env->now);
                if(!kkey) {
                        log_err("out of memory: allocate null prime key");
@@ -2469,8 +2472,9 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
                /* errors here pretty much break validation */
                verbose(VERB_DETAIL, "DS response was error, thus bogus");
                errinf(qstate, rc);
-               errinf_ede(qstate, "no DS", LDNS_EDE_NETWORK_ERROR);
-
+               reason = "no DS";
+               reason_bogus = LDNS_EDE_NETWORK_ERROR;
+               errinf_ede(qstate, reason, reason_bogus);
                goto return_bogus;
        }
 
@@ -2484,7 +2488,8 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
                if(!ds) {
                        log_warn("internal error: POSITIVE DS response was "
                                "missing DS.");
-                       errinf_ede(qstate, "no DS record", LDNS_EDE_DNSSEC_BOGUS);
+                       reason = "no DS record";
+                       errinf_ede(qstate, reason, reason_bogus);
                        goto return_bogus;
                }
                /* Verify only returns BOGUS or SECURE. If the rrset is 
@@ -2503,13 +2508,11 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
                if(!val_dsset_isusable(ds)) {
                        /* If they aren't usable, then we treat it like 
                         * there was no DS. */
-
-                       /* TODO add EDE Unsupported DS Digest Type; this needs
-                        * EDE to be added on non SERVFAIL answers. */
-
-                       *ke = key_entry_create_null(qstate->region, 
-                               qinfo->qname, qinfo->qname_len, qinfo->qclass, 
-                               ub_packed_rrset_ttl(ds), *qstate->env->now);
+                       *ke = key_entry_create_null(qstate->region,
+                               qinfo->qname, qinfo->qname_len, qinfo->qclass,
+                               ub_packed_rrset_ttl(ds),
+                               LDNS_EDE_UNSUPPORTED_DS_DIGEST, NULL,
+                               *qstate->env->now);
                        return (*ke) != NULL;
                }
 
@@ -2517,7 +2520,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
                log_query_info(VERB_DETAIL, "validated DS", qinfo);
                *ke = key_entry_create_rrset(qstate->region,
                        qinfo->qname, qinfo->qname_len, qinfo->qclass, ds,
-                       NULL, *qstate->env->now);
+                       NULL, LDNS_EDE_NONE, NULL, *qstate->env->now);
                return (*ke) != NULL;
        } else if(subtype == VAL_CLASS_NODATA || 
                subtype == VAL_CLASS_NAMEERROR) {
@@ -2529,7 +2532,8 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
                /* make sure there are NSECs or NSEC3s with signatures */
                if(!val_has_signed_nsecs(msg->rep, &reason)) {
                        verbose(VERB_ALGO, "no NSECs: %s", reason);
-                       errinf_ede(qstate, reason, LDNS_EDE_NSEC_MISSING);
+                       reason_bogus = LDNS_EDE_NSEC_MISSING;
+                       errinf_ede(qstate, reason, reason_bogus);
                        goto return_bogus;
                }
 
@@ -2541,7 +2545,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
                /* Try to prove absence of the DS with NSEC */
                sec = val_nsec_prove_nodata_dsreply(
                        qstate->env, ve, qinfo, msg->rep, vq->key_entry, 
-                       &proof_ttl, &reason, qstate);
+                       &proof_ttl, &reason, &reason_bogus, qstate);
                switch(sec) {
                        case sec_status_secure:
                                verbose(VERB_DETAIL, "NSEC RRset for the "
@@ -2549,6 +2553,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
                                *ke = key_entry_create_null(qstate->region, 
                                        qinfo->qname, qinfo->qname_len, 
                                        qinfo->qclass, proof_ttl,
+                                       LDNS_EDE_NONE, NULL,
                                        *qstate->env->now);
                                return (*ke) != NULL;
                        case sec_status_insecure:
@@ -2582,6 +2587,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
                                *ke = key_entry_create_null(qstate->region, 
                                        qinfo->qname, qinfo->qname_len, 
                                        qinfo->qclass, proof_ttl,
+                                       LDNS_EDE_NONE, NULL,
                                        *qstate->env->now);
                                return (*ke) != NULL;
                        case sec_status_indeterminate:
@@ -2604,7 +2610,8 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
                 * this is BOGUS. */
                verbose(VERB_DETAIL, "DS %s ran out of options, so return "
                        "bogus", val_classification_to_string(subtype));
-               errinf(qstate, "no DS but also no proof of that");
+               reason = "no DS but also no proof of that";
+               errinf_ede(qstate, reason, reason_bogus);
                goto return_bogus;
        } else if(subtype == VAL_CLASS_CNAME || 
                subtype == VAL_CLASS_CNAMENOANSWER) {
@@ -2616,22 +2623,25 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
                cname = reply_find_rrset_section_an(msg->rep, qinfo->qname,
                        qinfo->qname_len, LDNS_RR_TYPE_CNAME, qinfo->qclass);
                if(!cname) {
-                       errinf(qstate, "validator classified CNAME but no "
-                               "CNAME of the queried name for DS");
+                       reason = "validator classified CNAME but no "
+                               "CNAME of the queried name for DS";
+                       errinf_ede(qstate, reason, reason_bogus);
                        goto return_bogus;
                }
                if(((struct packed_rrset_data*)cname->entry.data)->rrsig_count
                        == 0) {
                        if(msg->rep->an_numrrsets != 0 && ntohs(msg->rep->
                                rrsets[0]->rk.type)==LDNS_RR_TYPE_DNAME) {
-                               errinf(qstate, "DS got DNAME answer");
+                               reason = "DS got DNAME answer";
                        } else {
-                               errinf(qstate, "DS got unsigned CNAME answer");
+                               reason = "DS got unsigned CNAME answer";
                        }
+                       errinf_ede(qstate, reason, reason_bogus);
                        goto return_bogus;
                }
-               sec = val_verify_rrset_entry(qstate->env, ve, cname, 
-                       vq->key_entry, &reason, NULL, LDNS_SECTION_ANSWER, qstate);
+               sec = val_verify_rrset_entry(qstate->env, ve, cname,
+                       vq->key_entry, &reason, &reason_bogus,
+                       LDNS_SECTION_ANSWER, qstate);
                if(sec == sec_status_secure) {
                        verbose(VERB_ALGO, "CNAME validated, "
                                "proof that DS does not exist");
@@ -2640,12 +2650,13 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
                        return 1;
                }
                errinf(qstate, "CNAME in DS response was not secure.");
-               errinf(qstate, reason);
+               errinf_ede(qstate, reason, reason_bogus);
                goto return_bogus;
        } else {
                verbose(VERB_QUERY, "Encountered an unhandled type of "
                        "DS response, thus bogus.");
                errinf(qstate, "no DS and");
+               reason = "no DS";
                if(FLAGS_GET_RCODE(msg->rep->flags) != LDNS_RCODE_NOERROR) {
                        char rc[16];
                        rc[0]=0;
@@ -2658,8 +2669,8 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
        }
 return_bogus:
        *ke = key_entry_create_bad(qstate->region, qinfo->qname,
-               qinfo->qname_len, qinfo->qclass, 
-               BOGUS_KEY_TTL, *qstate->env->now);
+               qinfo->qname_len, qinfo->qclass, BOGUS_KEY_TTL,
+               reason_bogus, reason, *qstate->env->now);
        return (*ke) != NULL;
 }
 
@@ -2779,14 +2790,17 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
                        vq->restart_count++;
                        return;
                }
-               vq->key_entry = key_entry_create_bad(qstate->region, 
+               reason = "No DNSKEY record";
+               reason_bogus = LDNS_EDE_DNSKEY_MISSING;
+               vq->key_entry = key_entry_create_bad(qstate->region,
                        qinfo->qname, qinfo->qname_len, qinfo->qclass,
-                       BOGUS_KEY_TTL, *qstate->env->now);
+                       BOGUS_KEY_TTL, reason_bogus, reason,
+                       *qstate->env->now);
                if(!vq->key_entry) {
                        log_err("alloc failure in missing dnskey response");
                        /* key_entry is NULL for failure in Validate */
                }
-               errinf_ede(qstate, "No DNSKEY record", LDNS_EDE_DNSKEY_MISSING);
+               errinf_ede(qstate, reason, reason_bogus);
                errinf_origin(qstate, origin);
                errinf_dname(qstate, "for key", qinfo->qname);
                vq->state = VAL_VALIDATE_STATE;
@@ -2833,7 +2847,8 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
        qstate->errinf = NULL;
 
        /* The DNSKEY validated, so cache it as a trusted key rrset. */
-       key_cache_insert(ve->kcache, vq->key_entry, qstate);
+       key_cache_insert(ve->kcache, vq->key_entry,
+               qstate->env->cfg->val_log_level >= 2);
 
        /* If good, we stay in the FINDKEY state. */
        log_query_info(VERB_DETAIL, "validated DNSKEY", qinfo);
@@ -2901,7 +2916,8 @@ process_prime_response(struct module_qstate* qstate, struct val_qstate* vq,
                errinf_origin(qstate, origin);
                errinf_dname(qstate, "for trust anchor", ta->name);
                /* store the freshly primed entry in the cache */
-               key_cache_insert(ve->kcache, vq->key_entry, qstate);
+               key_cache_insert(ve->kcache, vq->key_entry,
+                       qstate->env->cfg->val_log_level >= 2);
        }
 
        /* If the result of the prime is a null key, skip the FINDKEY state.*/