]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix chain of trust with CNAME at an intermediate step, for the DS
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 9 Apr 2010 14:28:32 +0000 (14:28 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 9 Apr 2010 14:28:32 +0000 (14:28 +0000)
          processing proof.

git-svn-id: file:///svn/unbound/trunk@2075 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
testdata/val_ds_cname.rpl [new file with mode: 0644]
validator/validator.c

index 62dbf3b364e40ace5c8c5ef5c0b4a42c9b00ef7e..b0e5ce54b6774c89022766773b4bdac8586f3273 100644 (file)
@@ -2,6 +2,8 @@
        - Fix bug#305: pkt_dname_tolower could read beyond end of buffer or
          get into an endless loop, if 0x20 was enabled, and buffers are small
          or particular broken packets are received.
+       - Fix chain of trust with CNAME at an intermediate step, for the DS
+         processing proof.
 
 8 April 2010: Wouter
        - Fix validation of queries with wildcard names (*.example).
diff --git a/testdata/val_ds_cname.rpl b/testdata/val_ds_cname.rpl
new file mode 100644 (file)
index 0000000..e5e1c19
--- /dev/null
@@ -0,0 +1,186 @@
+; config options
+; The island of trust is at example.com
+server:
+       trust-anchor: "example.com.    3600    IN      DS      2854 3 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 CNAME response to DS 
+
+; 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
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+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 AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+; nothing here, not even NSECs
+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
+ENTRY_END
+
+; DS query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN DS
+SECTION ANSWER
+www.example.com. IN CNAME zzz.example.com.
+www.example.com.       3600    IN      RRSIG   CNAME 3 2 3600 20070926134150 20070829134150 2854 example.com. AERsv3PiBObAEhZ/dKyamie0sjvYLn7YaEKgv9ExB14KKLgWvzCaOWo= ;{id = 2854}
+;*.example.com. IN CNAME zzz.example.com.
+;*.example.com.        3600    IN      RRSIG   CNAME 3 2 3600 20070926134150 20070829134150 2854 example.com. AERsv3PiBObAEhZ/dKyamie0sjvYLn7YaEKgv9ExB14KKLgWvzCaOWo= ;{id = 2854}
+
+SECTION AUTHORITY
+*.example.com. IN NSEC zzz.example.com. CNAME RRSIG NSEC
+*.example.com. 3600    IN      RRSIG   NSEC 3 2 3600 20070926134150 20070829134150 2854 example.com. AJxl2TXciyhbKqSakVNtjlt8Bbkco02zpl5RlY88iqVmSa6ts+/guU4= ;{id = 2854}
+zzz.example.com. IN NSEC *.zzz.example.com. A RRSIG NSEC
+zzz.example.com.       3600    IN      RRSIG   NSEC 3 3 3600 20070926134150 20070829134150 2854 example.com. ACtgx/h0YfGEK79zg4G16jB/0oRWH0nxrMzUc/4hCY3oprsP8DrdjqU= ;{id = 2854}
+example.com. IN SOA alfa.ns.example.com.cz. hostmaster.example.com. 2010030800 10800 86400 604800 86400
+example.com.   3600    IN      RRSIG   SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. ADsxLOHjxFzwFmwIiGOubqD9nKWAp4RccRIXQ0+EAUGfSDZMCB0ZiFA= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+zzz.example.com. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+zzz.example.com. IN NSEC *.zzz.example.com. A RRSIG NSEC
+zzz.example.com.       3600    IN      RRSIG   NSEC 3 3 3600 20070926134150 20070829134150 2854 example.com. ACtgx/h0YfGEK79zg4G16jB/0oRWH0nxrMzUc/4hCY3oprsP8DrdjqU= ;{id = 2854}
+example.com. IN SOA alfa.ns.example.com.cz. hostmaster.example.com. 2010030800 10800 86400 604800 86400
+example.com.   3600    IN      RRSIG   SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. ADsxLOHjxFzwFmwIiGOubqD9nKWAp4RccRIXQ0+EAUGfSDZMCB0ZiFA= ;{id = 2854}
+SECTION ADDITIONAL
+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 SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
+SCENARIO_END
index 650b689585ff70163b048e03c6c85ce006d5940a..fe762b79830d2b241f888643076b1931efd10936 100644 (file)
@@ -1421,6 +1421,8 @@ processFindKey(struct module_qstate* qstate, struct val_qstate* vq, int id)
                        vq->empty_DS_name) == 0) {
                        /* do not query for empty_DS_name again */
                        verbose(VERB_ALGO, "Cannot retrieve DS for signature");
+                       errinf(qstate, "no signatures");
+                       errinf_origin(qstate, qstate->reply_origin);
                        vq->chase_reply->security = sec_status_bogus;
                        vq->state = VAL_FINISHED_STATE;
                        return 1;
@@ -2453,6 +2455,42 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
                        "bogus", val_classification_to_string(subtype));
                errinf(qstate, "no DS but also no proof of that");
                goto return_bogus;
+       } else if(subtype == VAL_CLASS_CNAME || 
+               subtype == VAL_CLASS_CNAMENOANSWER) {
+               /* if the CNAME matches the exact name we want and is signed
+                * properly, then also, we are sure that no DS exists there,
+                * much like a NODATA proof */
+               enum sec_status sec;
+               struct ub_packed_rrset_key* cname;
+               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");
+                       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");
+                       } else {
+                               errinf(qstate, "DS got unsigned CNAME answer");
+                       }
+                       goto return_bogus;
+               }
+               sec = val_verify_rrset_entry(qstate->env, ve, cname, 
+                       vq->key_entry, &reason);
+               if(sec == sec_status_secure) {
+                       verbose(VERB_ALGO, "CNAME validated, "
+                               "proof that DS does not exist");
+                       /* and that it is not a referral point */
+                       *ke = NULL;
+                       return 1;
+               }
+               errinf(qstate, "CNAME in DS response was not secure.");
+               errinf(qstate, reason);
+               goto return_bogus;
        } else {
                verbose(VERB_QUERY, "Encountered an unhandled type of "
                        "DS response, thus bogus.");