]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix handling of wildcard CNAMEs in the chain of trust.
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Tue, 21 Apr 2026 11:24:40 +0000 (13:24 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Tue, 21 Apr 2026 11:24:40 +0000 (13:24 +0200)
  An improper wildcard in the chain of trust would send
  the retries to the wrong upstream. Also it could label
  the step in the chain of trust as secure, when it was not.
  Thanks to Qifan Zhang, Palo Alto Networks for the report.

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

index 12dfb3559603db9310d60a0bae4dd21c786a399f..c055eb59baf961ad2a3daeb2c4add1d4d469a9e8 100644 (file)
          configurations an unchecked unsigned CNAME could get
          secure status. Thanks to Qifan Zhang, Palo Alto Networks
          for the report.
+       - Fix handling of wildcard CNAMEs in the chain of trust.
+         An improper wildcard in the chain of trust would send
+         the retries to the wrong upstream. Also it could label
+         the step in the chain of trust as secure, when it was not.
+         Thanks to Qifan Zhang, Palo Alto Networks for the report.
 
 20 April 2026: Wouter
        - Fix compile warnings for thread setname routine, and test compile.
diff --git a/testdata/ds_wildcard_cname.rpl b/testdata/ds_wildcard_cname.rpl
new file mode 100644 (file)
index 0000000..37b0bae
--- /dev/null
@@ -0,0 +1,374 @@
+; config options
+; The island of trust is at test.
+server:
+       trust-anchor: "test. DS 1444 8 2 8a87d067fd09a5965244fe2e317dd26d182c468e0a7f26ecc4c7b479bf89db9b"
+       val-override-date: "20201020135527"
+       target-fetch-policy: "0 0 0 0 0"
+       qname-minimisation: "no"
+       fake-sha1: yes
+       trust-anchor-signaling: no
+       minimal-responses: no
+       iter-scrub-promiscuous: no
+       aggressive-nsec: yes
+       local-zone: test. nodefault
+       log-servfail: yes
+
+stub-zone:
+       name: "."
+       stub-addr: 193.0.14.129         # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test DS response with wildcard CNAME
+
+; 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 subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+test. IN NS
+SECTION AUTHORITY
+test.  IN NS   ns.test.
+SECTION ADDITIONAL
+ns.test. IN A 1.2.3.5
+ENTRY_END
+RANGE_END
+
+; ns.test
+RANGE_BEGIN 0 100
+       ADDRESS 1.2.3.5
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+test. IN NS
+SECTION ANSWER
+test.    IN NS   ns.test
+test.  3600    IN      RRSIG   NS 8 1 3600 20201116135527 20201019135527 1444 test. RGCxIO32TbbLTk6xZmTr+fjYPH50hntBxeOQ2DIj2pDsmjALcHYtVkOfpfk2EhOhHZd+9PLuoJPbJh6a9NqLSFeBvr0XZoCZoQ2g0tCHUNHcH5EVjA2TuYBQem6DVYnPLJ3914aRx0uA1j42b8dC2xsam/XkOo7U+dLbUW2Os1s=
+SECTION ADDITIONAL
+ns.test. IN A 1.2.3.5
+ns.test.       3600    IN      RRSIG   A 8 2 3600 20201116135527 20201019135527 1444 test. GskCc4/k6GjH9V9Jz2V5L2XLiizbOeWkB0feSbf+aN859S3vxVvtuqkvIgwY4LafUO1QAn/pUcv9zA7rcFO++rlg+8t6gvZTo9p3v0bfeIv2uJDsfSBD5jDh0WXlxjekfnrKrQp7zE+GiA93tWwKUWKPvxXDgP+n886e6WcbHJw=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.test. IN A
+SECTION ANSWER
+ns.test. IN A 1.2.3.5
+ns.test.       3600    IN      RRSIG   A 8 2 3600 20201116135527 20201019135527 1444 test. GskCc4/k6GjH9V9Jz2V5L2XLiizbOeWkB0feSbf+aN859S3vxVvtuqkvIgwY4LafUO1QAn/pUcv9zA7rcFO++rlg+8t6gvZTo9p3v0bfeIv2uJDsfSBD5jDh0WXlxjekfnrKrQp7zE+GiA93tWwKUWKPvxXDgP+n886e6WcbHJw=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.test. IN AAAA
+SECTION AUTHORITY
+test. 3600 IN SOA ns.test. host.test. 20201 3600 1800 604800 3600
+test.  3600    IN      RRSIG   SOA 8 1 3600 20201116135527 20201019135527 1444 test. IZJIDmEgf0W7A5G7hvvZ2hUqJ9Trbv1/i7ySapDmPbYV9lVCmHHobySxO01yDhI2/Pvpsvxqrm1Tiv3BxH8uzZ4keKgiQjBsSy4htAsFct9I4E7ly2glPj/Fm3oun3PsjJDv5QYhx0KS7w4IQKU7Nc9pfJc92uoUI5bdoC1pRGw=
+ns.test. 3600 IN NSEC nz.test. A RRSIG
+ns.test.       3600    IN      RRSIG   NSEC 8 2 3600 20201116135527 20201019135527 1444 test. PElArVB3KPg8KHAP7lzcNbhFuXNxTsHNTn1dZVncB5qmWRdIaeKpaXDjpH0JSXMaelGFS+/QhuQ6Hmw9+4VyZFRqMzGhw4agUR/2bxABHcDIG4ZpUwyeSP61ATTfHUkQVxaH2wjCWI/tfmesdP2xVE4GXyUvCIBxU914MkZbULU=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+test. IN DNSKEY
+SECTION ANSWER
+test.    3600    IN      DNSKEY  257 3 8 AwEAAbd9WqjzE2Pynz21OG5doSf9hFzMr5dhzz2waZ3vTa+0o5r7AjTAqmA1yH/B3+aAMihUm5ucZSfVqo7+kOaRE8yFj9aivOmA1n1+JLevJq/oyvQyjxQN2Qb89LyaNUT5oKZIiL+uyyhNW3KDR3SSbQ/GBwQNDHVcZi+JDR3RC0r7 ;{id = 1444 (ksk), size = 1024b}
+test.  3600    IN      RRSIG   DNSKEY 8 1 3600 20201116135527 20201019135527 1444 test. UmRMS4iG9NBBHZYOtpwFFcJgbEb5SfHSgHd9XRe/8pTWM31WSDayn5ViPOBMqI1T5TXg2amc13dDI574xIM2oKMus3b5cBW72jJLW13jprBtslO6P8BMWb4HNnvLrJtQjwf3ErRirtTxinLmywQtmyr1cdthyG3Gp4N7i90fHSc=
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.test. IN DS
+SECTION ANSWER
+example.test.  3600    IN      DS      55567 8 2 a2d578906330a10a57d40462257b6ce038bad3f7bf4a45c46c46086e20a94b39
+example.test.  3600    IN      RRSIG   DS 8 2 3600 20201116135527 20201019135527 1444 test. P7+FTYW2qHuJ4I1YbuvseEz5X1lOYAraGEHB3C5y0OOCQFmhmSiFRdquNi2NlpcS6FXLdsE0EU+Bo1+0atTG4EkMWXbpF21lrtbB51BdsnlX4Mzc/o375fvjiOMwmF6wPCUaOUN62jrVrhsE/hedaVyDphDToqL17ETohwgUO2I=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.test. IN NS
+SECTION AUTHORITY
+example.test.    IN NS   ns.example.test.
+example.test.  3600    IN      DS      55567 8 2 a2d578906330a10a57d40462257b6ce038bad3f7bf4a45c46c46086e20a94b39
+example.test.  3600    IN      RRSIG   DS 8 2 3600 20201116135527 20201019135527 1444 test. P7+FTYW2qHuJ4I1YbuvseEz5X1lOYAraGEHB3C5y0OOCQFmhmSiFRdquNi2NlpcS6FXLdsE0EU+Bo1+0atTG4EkMWXbpF21lrtbB51BdsnlX4Mzc/o375fvjiOMwmF6wPCUaOUN62jrVrhsE/hedaVyDphDToqL17ETohwgUO2I=
+SECTION ADDITIONAL
+ns.example.test. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.test.
+RANGE_BEGIN 0 100
+       ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.test. IN NS
+SECTION ANSWER
+example.test.    IN NS   ns.example.test.
+example.test.  3600    IN      RRSIG   NS 8 2 3600 20201116135527 20201019135527 55567 example.test. l1JT0wMlK0YI7/CWHzexf/k0iafUhCgN+BdgjBXIRXmSQNf4HDTiAkbcWL2/15qtnp12nQy9JeiTdSQ3vtPoHAJX4C5uTWaze4ms+Wrrf+n92sLCjacP9x50uuicH3URT6cKb1QCAPwlvlWxIlZjAMYFScSns7+C441NMJT8aE4=
+SECTION ADDITIONAL
+ns.example.test.         IN      A       1.2.3.4
+ns.example.test.       3600    IN      RRSIG   A 8 3 3600 20201116135527 20201019135527 55567 example.test. 2PWaVaccZFQgfPKXNsdEGYUVaashCAj1ZhBo9XRt5eQKUFvZcauBjMnXIuxZFyWeootn1fZGw6GuPI5W48Y0FDx38H6adprkFgQikso2Y64jDdDMWznSo38Z/XqP+U0+kq4vmwonvmEMpm7hKnNEXvhqGKyGzyBwb+CZVJ2L8Eo=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.test. IN A
+SECTION ANSWER
+ns.example.test.         IN      A       1.2.3.4
+ns.example.test.       3600    IN      RRSIG   A 8 3 3600 20201116135527 20201019135527 55567 example.test. 2PWaVaccZFQgfPKXNsdEGYUVaashCAj1ZhBo9XRt5eQKUFvZcauBjMnXIuxZFyWeootn1fZGw6GuPI5W48Y0FDx38H6adprkFgQikso2Y64jDdDMWznSo38Z/XqP+U0+kq4vmwonvmEMpm7hKnNEXvhqGKyGzyBwb+CZVJ2L8Eo=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.test. IN AAAA
+SECTION ANSWER
+ns.example.test. 3600 IN AAAA 2001::1:2:3:4
+ns.example.test.       3600    IN      RRSIG   AAAA 8 3 3600 20201116135527 20201019135527 55567 example.test. IuFmNUqxRjWSw/Ua2A0XmeKbsVkw6Yzd/D4TGBZ5pyKtbYIFvmF/QfcqzONiwqG3KEW2tAeyEjZOYjrM37NqgIwwk56LJ16fFA7e2tShjSjPhgNzjHZW9zvFTjPyTTVpMVb3SGV59RQTm3jJwlQCq7qVHyKQ+HT3pa+XZQJEzdw=
+SECTION AUTHORITY
+;example.test. 3600 IN SOA ns.example.test. host.example.test. 20301 3600 1800 604800 3600
+;example.test. 3600    IN      RRSIG   SOA 8 2 3600 20201116135527 20201019135527 55567 example.test. 2UUkScBAN37fJpSrelhE8DotKvmOzj3q9wicaanCIaCv95DE4nQnePih5B+ek3FIRjB/Uv2+z4Ro5Uxy94XAnlK0rCkDLSa0U9U7KP0ytc88sevO0x1SCPAMoZoJO6JqHkv42pdh54WSz+Zb/D8npY0j/tksHe/uX+VQnMymgb8=
+;ns.example.test. 3600 IN NSEC nz.example.test. A RRSIG
+;ns.example.test.      3600    IN      RRSIG   NSEC 8 3 3600 20201116135527 20201019135527 55567 example.test. v/5aO/n8Ow21y7LE7JKZsFkUJU5MjIfadVRm2Tdb8f3RLwYDdBTs3aWeeEQdCRSUF61TmfJM1jIxlWQPuHbqzGnjSk7adw9gFpP7wFwoqG3/xdCFHoxo/3/1F/4Ankey3sDgKgOFsgnu40TlL36mGPYszeK+/2o3SAx2GM+3BdU=
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.test. IN DNSKEY
+SECTION ANSWER
+example.test.  3600    IN      DNSKEY  257 3 8 AwEAAdug/L739i0mgN2nuK/bhxu3wFn5Ud9nK2+XUmZQlPUEZUC5YZvm1rfMmEWTGBn87fFxEu/kjFZHJ55JLzqsbbpVHLbmKCTT2gYR2FV2WDKROGKuYbVkJIXdKAjJ0ONuK507NinYvlWXIoxHn22KAWOd9wKgSTNHBlmGkX+ts3hh ;{id = 55567 (ksk), size = 1024b}
+example.test.  3600    IN      RRSIG   DNSKEY 8 2 3600 20201116135527 20201019135527 55567 example.test. IbWMC6quOuZFNPAVxQLqCJ9nLhindBo826rnLcg5yMgs9dGUSPOCXAfHTmbgJAUNs9HTFfrJWNvasnETs0UOpmEuifGwWdH1OlME7Gny4RL2QmITUFeMW81Jz1tiVQxFXl6yxT0jxOxvz+bqMHlrz+8IeWQXcO+GZTPu8ueq30g=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+tgt.example.test. DS
+SECTION ANSWER
+SECTION AUTHORITY
+; denial of the DS record for tgt.example.test.
+example.test. 3600 IN SOA ns.example.test. host.example.test. 20301 3600 1800 604800 3600
+example.test.  3600    IN      RRSIG   SOA 8 2 3600 20201116135527 20201019135527 55567 example.test. 2UUkScBAN37fJpSrelhE8DotKvmOzj3q9wicaanCIaCv95DE4nQnePih5B+ek3FIRjB/Uv2+z4Ro5Uxy94XAnlK0rCkDLSa0U9U7KP0ytc88sevO0x1SCPAMoZoJO6JqHkv42pdh54WSz+Zb/D8npY0j/tksHe/uX+VQnMymgb8=
+tgt.example.test. 3600 IN NSEC tgz.example.test. A RRSIG
+tgt.example.test.      3600    IN      RRSIG   NSEC 8 3 3600 20201116135527 20201019135527 55567 example.test. R9v8k/M56dLOUbrTP/m2XnKsOjIj1kAfwCQvHW4KPdDn3XJIvCLs4mTjxvyQ70uP+zA8WxrPgbqPZv//Ms3Sher2j41VKIBRFkJpyJn6/D9/QmOOhWzoPYXuujHJAkB9IDit3YOgJutirFnB7reTTav42P5x7PzQDSt+crUnXkw=
+ENTRY_END
+
+; when there is a re-query for the DS record, this answer is used.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.test. IN DS
+SECTION ANSWER
+; This reply is an injected reply.
+sub.example.test. 300 IN CNAME tgt.example.test.
+; signature for wildcard, *.example.test. 300 IN CNAME tgt.example.test.
+sub.example.test.      300     IN      RRSIG   CNAME 8 2 300 20201116135527 20201019135527 55567 example.test. fz+xLPcRAbGUcnF7hITQHRT6AeA/I/dSjyLWb3it+cHSMY7dN4Jpw7Dk0GJh0y71HXFwaWgk1If0O4IOVo4mfkm1RrRhBnxJT8R88AQlN69SXLZrlHIhoupBpZADz/J15hOcHG+/1svsEpAA5qkOrgZwf581X9ygwPGFkIHgS+o=
+ENTRY_END
+
+; The referral to sub.example.test, for other queries than type DS.
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.test. IN NS
+SECTION ANSWER
+SECTION AUTHORITY
+sub.example.test. 3600 NS ns.sub.example.test.
+; Smaller TTL 300 for the DS.
+sub.example.test.      300     IN      DS      29332 8 2 69c8a09889e377fb1d1af78cc55984152adf25f4643b26d42654657a171e92aa
+sub.example.test.      300     IN      RRSIG   DS 8 3 300 20201116135527 20201019135527 55567 example.test. vyjkyx1UMCI5KftU7BQWxDkxNj25A60haEIR/Sy7JUkG2UnE0tNIVNE4mEmUGX6ICsddKGwba2xFQFYBMyfpnzsNxEMKv8VpOGObpiTlK4ICRaq6m+pVND1Benk6grzkb+6T2xogHEEMYqnMUF4bDGRe5tcftS9XdAl77pG6W7Q=
+SECTION ADDITIONAL
+ns.sub.example.test. IN A 1.2.3.7
+ENTRY_END
+RANGE_END
+
+; ns.sub.example.test.
+RANGE_BEGIN 0 100
+       ADDRESS 1.2.3.7
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.sub.example.test. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+sub.example.test. 3600 IN SOA ns.sub.example.test. host.sub.example.test. 20701 3600 1800 604800 3600
+sub.example.test.      3600    IN      RRSIG   SOA 8 3 3600 20201116135527 20201019135527 29332 sub.example.test. EEeC/XlG/XuItqRphAOREwHPzqSsJSs9TEhPnqOzXU4/+j0Eq05WN8ZE+GxHnmrxzaLiqAT6pLYLaQxCFcpkMVKUFYfMFyK6jOkTHZ1ODXNIdAA/ZGMCOQQUco3rcrY6F2U8ETHSxiFQkEl8iQntWM6wUoUF37Yd4hab+o1eD/HZXKLwgNXbXC1iY40ZzqwAlxLcCt0SexiTI9BNfyDy3iROeT3XuloC2x9o2zclAqz3m42n8UKAs8Gh7sAkoTua2fqtNfWZtQctlp1tZgdJFXbI4vuxMEldD+Rh5kUJ72aXvD2W7vd042G7z3n+d+I4vtnH2qKNbVA4YHMXzA/3ug==
+ns.sub.example.test. 3600 IN NSEC nz.sub.example.test. A RRSIG
+ns.sub.example.test.   3600    IN      RRSIG   NSEC 8 4 3600 20201116135527 20201019135527 29332 sub.example.test. CqaJIHttjfPIdBM1Ty8RDGRnrkaoC7Y7pzS/Kbzjn3lsEJg2XPWZGRln75imsoVOdi46YG95HZdgvnndTAAH3dE0eZHycvo2O7zR0f+Ty3v/HWpvOsRp/XE/8/7g45DHLuyTXxiO6cDSu0bW/qTC4xyix7vMFNEyOmGMGIZEnvkoRWJvUToj8VW6r+a8dU1KIGQXKSXg3lRcXc0Zfk2lk5P0XGrGzdLcITbZbVP3aFgusoi6uCTqhPmwZRVJjuh1E0qXTTE2A67vloVBvwVxfhNajHNkVhEYtxqZyiRLPs1tRyWit4J2Kkk5qoWuPwNRoTHsgzmPJoDGxheUxGEvbA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.test. IN DNSKEY
+SECTION ANSWER
+sub.example.test. 300  IN      DNSKEY  257 3 8 AwEAAb4WMOTBLTFvmBra5m6SK4VfViOzmvyUAU0qv861ZQXeEFvwlndqNU9rwRsMxrSWAYs5nHErKDn49usC/HyxxW1477iGFHhfgL4mjNreJm9zft2QFB1VLbRbEPYdDMLCn4co0qnG7/KG8W2i8Pym1L7f+aREwbLo+/716AS2PbaKMhfWLKLiq5wnBcUClQMNzCiwhqxDJp1oePqfkVdeUgXOtgi0dYRIKyQFhJ5VWJ22npoi/Gif0XLCADAlAwRLKc8o/yJkCxskzgpHpw5Cki1lclg0aq4ssOuPRQ+ne6IHYCz9D2mwzulblhLFamKdq7aHzNt4NlyxhpANVFiKLD8= ;{id = 29332 (ksk), size = 2048b}
+sub.example.test.      300     IN      RRSIG   DNSKEY 8 3 300 20201116135527 20201019135527 29332 sub.example.test. j8lyYKogmlBon1WsYJp2H4DSdXZIGkzKHplH2hs9b5D2I+4kZ7jiwHz5/OZca5aOOE1QbhcPNRyhenSmtwePjhvBLSDDYC4OhowVpWW5o5aRQMnsTYZgmgqX0zPtUWBoK8P+GZRd1VO/Jam0qWoHjHY9lQlDnblN6f2yDRHQI2CVrSal8x12zl1s/QHVNpodb4MwowvL4WeGxDVxBOiS3v+9SobnfPa9oecu9onrcPryr4KDQHi6i5BNvHVPqE9eBkHnRe3DcvfEbOke6vZY7CCNgfGttaJL64ubCVUv2xu3okTQS5gSX9pRbjaxKlw1ZWmJR0HSq/dn2HDuWjzxkQ==
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.sub.example.test. IN A
+SECTION ANSWER
+a.sub.example.test. 300 IN A 10.20.30.40
+a.sub.example.test.    300     IN      RRSIG   A 8 4 300 20201116135527 20201019135527 29332 sub.example.test. lElblJBqr+LbNDO8mlyh9PbBzfC6LU5K8nh/fOHu9dFur5xuqtItw+D0/oo2ve6WIUnqblXKhfbZcKMa40DONog/uThmwyp6cBow7oZdfZSt5YTn74QwJb1M/yaJgU+OWNkM7RfG+VcvpB04+KH+g2qwEpHC5Jm5+e66beoiGHZuKle0qAxNAgM1kkJ5EdTngKk80YOciBv705xSSvySmCDktcIceV8zMgD9YFW1Q2I2SXtPCsVaJTA1jaf3Cm8rZfY1GrBW18JyLPOqf6eIBqdyXg/w/mi/pxgakIM3r9iKaDsEz01ZiN0jaEloteT+NhpjEJA/sFzu1nhV0Y3fJw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+b.sub.example.test. IN A
+SECTION ANSWER
+b.sub.example.test. 300 IN A 10.20.30.41
+b.sub.example.test.    300     IN      RRSIG   A 8 4 300 20201116135527 20201019135527 29332 sub.example.test. KimigOgfAWic9JVbuqMc0cE2aUlfzBaG+LjZl5IqZr7RLeImG74cpBMbTyzWJ1h3IhCKnLde3KMYz+viVEwsirxlY70i3cDObl5t9XlBKombQzCJBMv5MNCGH1iYfsBL6JVhVX849J1fRTK7E6mW2v9eN0GUFplTsThodnRnh/R3KYsn7wdYFAQ3VAkGzdrxcsS9Lmua1hYhJtjMFBuJn/pmoWpOWQePN9u9P1jh3IkvKN7XuwSYvoGjhE1ZM0OtpsWbHdYmFbUePu4Ruqk0Yg+eW1tkWBsj1AHq1x75BDxOShypi+8zb9zGeatF+A65PSOH1WjmpWNdbAYz97gssw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.sub.example.test. IN A
+SECTION ANSWER
+www.sub.example.test. 300 IN A 10.20.30.42
+www.sub.example.test.  300     IN      RRSIG   A 8 4 300 20201116135527 20201019135527 29332 sub.example.test. YuV5CADfhJ6yjxLrIZ243RvJmDJv0NgZKVZ9k5TorSY/O8fvPDzIMJFDjVs2gk6dZV81I6MmMbbcK5I3DEeBIHMswOZEhJYgfX7TiKi4sNfJQmyJJSx1SS1YQ38Asxst4cWgg5L6aoehsIlHvAqEz+JlObNus30nO7S6zMd+rFoThdbCpADK3AhbSI8xhO1u7Q8qgBchX7JZNIt5eiKnSrLSi5UAtuNMkczWv74ckFtd5PERpBGqpJRj50z0+7qiAbdahT3YQ7y2PkiBpZTtxG8Cmza4CkGPd1qzD/DRUsWOzZyiWwX5niD51sgqMj6ApGs8wbVSsk/vBudYw1/CIA==
+ENTRY_END
+RANGE_END
+
+; ns.example.test.
+RANGE_BEGIN 0 100
+       ADDRESS 2001::1:2:3:4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.test. IN DS
+SECTION ANSWER
+; This is the correct reply.
+sub.example.test.      300     IN      DS      29332 8 2 69c8a09889e377fb1d1af78cc55984152adf25f4643b26d42654657a171e92aa
+sub.example.test.      300     IN      RRSIG   DS 8 3 300 20201116135527 20201019135527 55567 example.test. vyjkyx1UMCI5KftU7BQWxDkxNj25A60haEIR/Sy7JUkG2UnE0tNIVNE4mEmUGX6ICsddKGwba2xFQFYBMyfpnzsNxEMKv8VpOGObpiTlK4ICRaq6m+pVND1Benk6grzkb+6T2xogHEEMYqnMUF4bDGRe5tcftS9XdAl77pG6W7Q=
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+a.sub.example.test. IN A
+ENTRY_END
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+a.sub.example.test. IN A
+SECTION ANSWER
+a.sub.example.test. 300 IN A 10.20.30.40
+a.sub.example.test.    300     IN      RRSIG   A 8 4 300 20201116135527 20201019135527 29332 sub.example.test. lElblJBqr+LbNDO8mlyh9PbBzfC6LU5K8nh/fOHu9dFur5xuqtItw+D0/oo2ve6WIUnqblXKhfbZcKMa40DONog/uThmwyp6cBow7oZdfZSt5YTn74QwJb1M/yaJgU+OWNkM7RfG+VcvpB04+KH+g2qwEpHC5Jm5+e66beoiGHZuKle0qAxNAgM1kkJ5EdTngKk80YOciBv705xSSvySmCDktcIceV8zMgD9YFW1Q2I2SXtPCsVaJTA1jaf3Cm8rZfY1GrBW18JyLPOqf6eIBqdyXg/w/mi/pxgakIM3r9iKaDsEz01ZiN0jaEloteT+NhpjEJA/sFzu1nhV0Y3fJw==
+ENTRY_END
+
+STEP 20 TIME_PASSES ELAPSE 320
+; The DS record has expired, but the NS record for sub.example.test. is in
+; cache.
+
+; The DS lookup fails with wildcard CNAME.
+; Then it should blacklist the parent (1.2.3.4) not the sub zone (1.2.3.7)
+; the AAAA for the parent can then be retrieved, and it is used.
+
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.sub.example.test. IN A
+ENTRY_END
+
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.sub.example.test. IN A
+SECTION ANSWER
+www.sub.example.test. 300 IN A 10.20.30.42
+www.sub.example.test.  300     IN      RRSIG   A 8 4 300 20201116135527 20201019135527 29332 sub.example.test. YuV5CADfhJ6yjxLrIZ243RvJmDJv0NgZKVZ9k5TorSY/O8fvPDzIMJFDjVs2gk6dZV81I6MmMbbcK5I3DEeBIHMswOZEhJYgfX7TiKi4sNfJQmyJJSx1SS1YQ38Asxst4cWgg5L6aoehsIlHvAqEz+JlObNus30nO7S6zMd+rFoThdbCpADK3AhbSI8xhO1u7Q8qgBchX7JZNIt5eiKnSrLSi5UAtuNMkczWv74ckFtd5PERpBGqpJRj50z0+7qiAbdahT3YQ7y2PkiBpZTtxG8Cmza4CkGPd1qzD/DRUsWOzZyiWwX5niD51sgqMj6ApGs8wbVSsk/vBudYw1/CIA==
+ENTRY_END
+
+STEP 50 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+b.sub.example.test. IN A
+ENTRY_END
+
+STEP 60 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+b.sub.example.test. IN A
+SECTION ANSWER
+b.sub.example.test. 300 IN A 10.20.30.41
+b.sub.example.test.    300     IN      RRSIG   A 8 4 300 20201116135527 20201019135527 29332 sub.example.test. KimigOgfAWic9JVbuqMc0cE2aUlfzBaG+LjZl5IqZr7RLeImG74cpBMbTyzWJ1h3IhCKnLde3KMYz+viVEwsirxlY70i3cDObl5t9XlBKombQzCJBMv5MNCGH1iYfsBL6JVhVX849J1fRTK7E6mW2v9eN0GUFplTsThodnRnh/R3KYsn7wdYFAQ3VAkGzdrxcsS9Lmua1hYhJtjMFBuJn/pmoWpOWQePN9u9P1jh3IkvKN7XuwSYvoGjhE1ZM0OtpsWbHdYmFbUePu4Ruqk0Yg+eW1tkWBsj1AHq1x75BDxOShypi+8zb9zGeatF+A65PSOH1WjmpWNdbAYz97gssw==
+ENTRY_END
+
+SCENARIO_END
index a49c53538ebe08314aad3350d549e60480b59879..9a8919fb0005e42206fbc366fee24cf9edc7f968 100644 (file)
@@ -199,7 +199,7 @@ ENTRY_END
 ; recursion happens here.
 STEP 10 CHECK_ANSWER
 ENTRY_BEGIN
-MATCH all ede=10
+MATCH all ede=6
 REPLY QR RD RA DO SERVFAIL
 SECTION QUESTION
 www.example.com. IN A
@@ -215,7 +215,7 @@ ENTRY_END
 
 STEP 12 CHECK_ANSWER
 ENTRY_BEGIN
-MATCH all ede=10
+MATCH all ede=6
 REPLY QR RA DO SERVFAIL
 SECTION QUESTION
 www.example.com. IN A
index b3d55f07503affb0feb9cad1d88d7178c366f638..e7992b6e3711f50a5e4d480ceefaf7d01f27c5df 100644 (file)
@@ -3123,6 +3123,62 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
                        LDNS_SECTION_ANSWER, qstate, &verified, reasonbuf,
                        sizeof(reasonbuf));
                if(sec == sec_status_secure) {
+                       /* Check for wildcard expansion */
+                       uint8_t* wc = NULL;
+                       size_t wl = 0;
+
+                       if(!val_rrset_wildcard(cname, &wc, &wl)) {
+                               verbose(VERB_ALGO, "CNAME has inconsistent wildcard signatures");
+                               reason = "wildcard CNAME inconsistent signatures";
+                               errinf_ede(qstate, reason, reason_bogus);
+                               goto return_bogus;
+                       }
+
+                       if(wc != NULL) {
+                               /* Wildcard expansion detected - require NSEC proof */
+                               /* So this is a wildcard CNAME response to DS.
+                                * If the wildcard is bogus then we have bogus.
+                                * If the wildcard is true, then there is
+                                * not a referral point here or lower,
+                                * that can be insecure,
+                                * and also no DS records, here or lower. */
+                               /* For a valid chain, to DS, but this
+                                * wildcard CNAME happens in a middle label,
+                                * then that can not happen, because there is
+                                * data under that label, and thus the wildcard
+                                * should not expand.
+                                * If we are going to the wildcard, that also
+                                * does not expand the wildcard, when above it.
+                                * So for valids lookup chains to DS, no
+                                * wildcard CNAME is expected on middle labels.
+                                * For lookups to an insecure point, the
+                                * delegation is information under the label,
+                                * and thus the wildcard does not expand.
+                                * So, no insecure point is possible.
+                                * Can not get a valid chain of trust, or
+                                * to a delegation point for insecure.
+                                * Or the wildcard, its nxdomain for the qname
+                                * proof, is invalid, in which case this is
+                                * a bogus reply.
+                                * If this was a lookup where a wildcard
+                                * expansion is genuinely expected, eg,
+                                * a dnssec valid wildcard query, then the
+                                * lookup should go to the right point, and
+                                * not into the wildcard under the zone name.
+                                * For insecure, or wildcard missing
+                                * signatures, it would have to have found
+                                * the DS or insecure point earlier, in the
+                                * downwards search.
+                                * So for missing signatures, it turns the
+                                * missing signatures into a failure to the
+                                * wildcard CNAME, as the reported log.
+                                */
+                               verbose(VERB_ALGO, "wildcard CNAME in chain of trust means no DS can be found and it is also not a delegation point that can be insecure");
+                               reason = "wildcard CNAME in chain of trust means no DS found and it is also not a delegation point that can be insecure";
+                               errinf_ede(qstate, reason, reason_bogus);
+                               goto return_bogus;
+                       }
+
                        verbose(VERB_ALGO, "CNAME validated, "
                                "proof that DS does not exist");
                        /* and that it is not a referral point */