From: Wouter Wijngaards Date: Thu, 16 Sep 2010 13:40:26 +0000 (+0000) Subject: - Algorithm rollover operational reality intrudes, for trust-anchor, X-Git-Tag: release-1.4.7rc1~90 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8b274b92aaaf3ade4278ced9ca1863615aed2887;p=thirdparty%2Funbound.git - Algorithm rollover operational reality intrudes, for trust-anchor, 5011-store, and DLV-anchor if one key matches it's good enough. git-svn-id: file:///svn/unbound/trunk@2235 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/doc/Changelog b/doc/Changelog index 8d4a5ce51..bc7dc9b69 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,7 @@ +16 September 2010: Wouter + - Algorithm rollover operational reality intrudes, for trust-anchor, + 5011-store, and DLV-anchor if one key matches it's good enough. + 15 September 2010: Wouter - Abide RFC5155 section 9.2: no AD flag for replies with NSEC3 optout. diff --git a/testcode/unitverify.c b/testcode/unitverify.c index 4679cef8d..ba5180e55 100644 --- a/testcode/unitverify.c +++ b/testcode/unitverify.c @@ -161,7 +161,7 @@ verifytest_rrset(struct module_env* env, struct val_env* ve, rrset->rk.dname, ntohs(rrset->rk.type), ntohs(rrset->rk.rrset_class)); } - sec = dnskeyset_verify_rrset(env, ve, rrset, dnskey, &reason); + sec = dnskeyset_verify_rrset(env, ve, rrset, dnskey, 1, &reason); if(vsig) { printf("verify outcome is: %s %s\n", sec_status_to_string(sec), reason?reason:""); diff --git a/testdata/val_ta_algo_dnskey.rpl b/testdata/val_ta_algo_dnskey.rpl new file mode 100644 index 000000000..f98f8b1c4 --- /dev/null +++ b/testdata/val_ta_algo_dnskey.rpl @@ -0,0 +1,167 @@ +; config options +; The island of trust is at example.com +server: + trust-anchor: "example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJIIs70j+sDS/UT2QRp61SE7S3EEXopNXoFE73JLRmvpi/UrOO/Vz4Se6wXv/CYCKjGw06U4WRgRYXcpEhJROyNapmdIKSxhOzfLVE1gqA0PweZR8dtY3aNQSRn3sPpwJr6Mi/PqQKAMMrZ9ckJpf1+bQMOOvxgzz2U1GS18b3yZKcgTMEaJzd/GZYzi/BN2DzQ0MsrSwYXfsNLFOBbs8PJMW4LYIxeeOe6rUgkWOF7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}" + trust-anchor: "example.com. 3600 IN DNSKEY 256 3 5 AQPQ41chR9DEHt/aIzIFAqanbDlRflJoRs5yz1jFsoRIT7dWf0r+PeDuewdxkszNH6wnU4QL8pfKFRh5PIYVBLK3 ;{id = 30899 (zsk), size = 512b}" + 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 multiple algorithm DS trust anchor + +; K.ROOT-SERVERS.NET. +RANGE_BEGIN 0 100 + ADDRESS 193.0.14.129 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +. IN NS +SECTION ANSWER +. IN NS K.ROOT-SERVERS.NET. +SECTION ADDITIONAL +K.ROOT-SERVERS.NET. IN A 193.0.14.129 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION AUTHORITY +com. IN NS a.gtld-servers.net. +SECTION ADDITIONAL +a.gtld-servers.net. IN A 192.5.6.30 +ENTRY_END +RANGE_END + +; a.gtld-servers.net. +RANGE_BEGIN 0 100 + ADDRESS 192.5.6.30 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +com. IN NS +SECTION ANSWER +com. IN NS a.gtld-servers.net. +SECTION ADDITIONAL +a.gtld-servers.net. IN A 192.5.6.30 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION AUTHORITY +example.com. IN NS ns.example.com. +SECTION ADDITIONAL +ns.example.com. IN A 1.2.3.4 +ENTRY_END +RANGE_END + +; ns.example.com. +RANGE_BEGIN 0 100 + ADDRESS 1.2.3.4 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +example.com. IN NS +SECTION ANSWER +example.com. IN NS ns.example.com. +example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} +SECTION ADDITIONAL +ns.example.com. IN A 1.2.3.4 +ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854} +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +ns.example.com. IN AAAA +SECTION ANSWER +SECTION AUTHORITY +example.com. IN NS ns.example.com. +example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} +SECTION ADDITIONAL +ns.example.com. IN A 1.2.3.4 +ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854} +ENTRY_END + + +; response to DNSKEY priming query +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +example.com. IN DNSKEY +SECTION ANSWER +example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b} +example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854} +SECTION AUTHORITY +example.com. IN NS ns.example.com. +example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} +SECTION ADDITIONAL +ns.example.com. IN A 1.2.3.4 +ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854} +ENTRY_END + +; response to query of interest +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +www.example.com. IN A 10.20.30.40 +ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} +SECTION AUTHORITY +example.com. IN NS ns.example.com. +example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} +SECTION ADDITIONAL +ns.example.com. IN A 1.2.3.4 +www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854} +ENTRY_END +RANGE_END + +STEP 1 QUERY +ENTRY_BEGIN +REPLY RD DO +SECTION QUESTION +www.example.com. IN A +ENTRY_END + +; recursion happens here. +STEP 10 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR RD RA AD NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +www.example.com. IN A 10.20.30.40 +www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854} +SECTION AUTHORITY +example.com. IN NS ns.example.com. +example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} +SECTION ADDITIONAL +ns.example.com. IN A 1.2.3.4 +ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} +ENTRY_END + +SCENARIO_END diff --git a/testdata/val_ta_algo_ds.rpl b/testdata/val_ta_algo_ds.rpl new file mode 100644 index 000000000..4f66a02d5 --- /dev/null +++ b/testdata/val_ta_algo_ds.rpl @@ -0,0 +1,167 @@ +; config options +; The island of trust is at example.com +server: + trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b" + trust-anchor: "example.com. 3600 IN DS 30899 5 1 d4bf9d2e10f6d76840d42ef5913022abcd0bf512" + 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 multiple algorithm DS trust anchor + +; K.ROOT-SERVERS.NET. +RANGE_BEGIN 0 100 + ADDRESS 193.0.14.129 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +. IN NS +SECTION ANSWER +. IN NS K.ROOT-SERVERS.NET. +SECTION ADDITIONAL +K.ROOT-SERVERS.NET. IN A 193.0.14.129 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION AUTHORITY +com. IN NS a.gtld-servers.net. +SECTION ADDITIONAL +a.gtld-servers.net. IN A 192.5.6.30 +ENTRY_END +RANGE_END + +; a.gtld-servers.net. +RANGE_BEGIN 0 100 + ADDRESS 192.5.6.30 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +com. IN NS +SECTION ANSWER +com. IN NS a.gtld-servers.net. +SECTION ADDITIONAL +a.gtld-servers.net. IN A 192.5.6.30 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION AUTHORITY +example.com. IN NS ns.example.com. +SECTION ADDITIONAL +ns.example.com. IN A 1.2.3.4 +ENTRY_END +RANGE_END + +; ns.example.com. +RANGE_BEGIN 0 100 + ADDRESS 1.2.3.4 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +example.com. IN NS +SECTION ANSWER +example.com. IN NS ns.example.com. +example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} +SECTION ADDITIONAL +ns.example.com. IN A 1.2.3.4 +ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854} +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +ns.example.com. IN AAAA +SECTION ANSWER +SECTION AUTHORITY +example.com. IN NS ns.example.com. +example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} +SECTION ADDITIONAL +ns.example.com. IN A 1.2.3.4 +ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854} +ENTRY_END + + +; response to DNSKEY priming query +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +example.com. IN DNSKEY +SECTION ANSWER +example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b} +example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854} +SECTION AUTHORITY +example.com. IN NS ns.example.com. +example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} +SECTION ADDITIONAL +ns.example.com. IN A 1.2.3.4 +ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854} +ENTRY_END + +; response to query of interest +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +www.example.com. IN A 10.20.30.40 +ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} +SECTION AUTHORITY +example.com. IN NS ns.example.com. +example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} +SECTION ADDITIONAL +ns.example.com. IN A 1.2.3.4 +www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854} +ENTRY_END +RANGE_END + +STEP 1 QUERY +ENTRY_BEGIN +REPLY RD DO +SECTION QUESTION +www.example.com. IN A +ENTRY_END + +; recursion happens here. +STEP 10 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR RD RA AD NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +www.example.com. IN A 10.20.30.40 +www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854} +SECTION AUTHORITY +example.com. IN NS ns.example.com. +example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} +SECTION ADDITIONAL +ns.example.com. IN A 1.2.3.4 +ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} +ENTRY_END + +SCENARIO_END diff --git a/validator/autotrust.c b/validator/autotrust.c index f31f62792..e43d94166 100644 --- a/validator/autotrust.c +++ b/validator/autotrust.c @@ -975,7 +975,7 @@ verify_dnskey(struct module_env* env, struct val_env* ve, if(tp->ds_rrset) { /* verify with ds, any will do to prime autotrust */ enum sec_status sec = val_verify_DNSKEY_with_DS( - env, ve, rrset, tp->ds_rrset, &reason); + env, ve, rrset, tp->ds_rrset, 0, &reason); verbose(VERB_ALGO, "autotrust: validate DNSKEY with DS: %s", sec_status_to_string(sec)); if(sec == sec_status_secure) { @@ -985,7 +985,7 @@ verify_dnskey(struct module_env* env, struct val_env* ve, if(tp->dnskey_rrset) { /* verify with keys */ enum sec_status sec = val_verify_rrset(env, ve, rrset, - tp->dnskey_rrset, &reason); + tp->dnskey_rrset, 0, &reason); verbose(VERB_ALGO, "autotrust: validate DNSKEY with keys: %s", sec_status_to_string(sec)); if(sec == sec_status_secure) { diff --git a/validator/val_sigcrypt.c b/validator/val_sigcrypt.c index 25790f583..1fe63c115 100644 --- a/validator/val_sigcrypt.c +++ b/validator/val_sigcrypt.c @@ -533,7 +533,7 @@ int algo_needs_missing(struct algo_needs* n) enum sec_status dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve, struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey, - char** reason) + int downprot, char** reason) { enum sec_status sec; size_t i, num; @@ -561,17 +561,19 @@ dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve, dnskey, i, &sortree, reason); /* see which algorithm has been fixed up */ if(sec == sec_status_secure) { - if(algo_needs_set_secure(&needs, + if(!downprot) + return sec; /* done! */ + else if(algo_needs_set_secure(&needs, (uint8_t)rrset_get_sig_algo(rrset, i))) return sec; /* done! */ - } else if(sec == sec_status_bogus) { + } else if(downprot && sec == sec_status_bogus) { algo_needs_set_bogus(&needs, (uint8_t)rrset_get_sig_algo(rrset, i)); } } verbose(VERB_ALGO, "rrset failed to verify: no valid signatures for " "%d algorithms", (int)algo_needs_num_missing(&needs)); - if((alg=algo_needs_missing(&needs)) != 0) { + if(downprot && (alg=algo_needs_missing(&needs)) != 0) { algo_needs_reason(env, alg, reason, "no signatures"); } return sec_status_bogus; diff --git a/validator/val_sigcrypt.h b/validator/val_sigcrypt.h index 3ced1e75a..d021e8b63 100644 --- a/validator/val_sigcrypt.h +++ b/validator/val_sigcrypt.h @@ -221,6 +221,8 @@ uint16_t dnskey_get_flags(struct ub_packed_rrset_key* k, size_t idx); * @param ve: validator environment, date settings. * @param rrset: to be validated. * @param dnskey: DNSKEY rrset, keyset to try. + * @param downprot: if true provide downgrade protection otherwise one + * algorithm is enough. * @param reason: if bogus, a string returned, fixed or alloced in scratch. * @return SECURE if one key in the set verifies one rrsig. * UNCHECKED on allocation errors, unsupported algorithms, malformed data, @@ -228,7 +230,7 @@ uint16_t dnskey_get_flags(struct ub_packed_rrset_key* k, size_t idx); */ enum sec_status dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve, struct ub_packed_rrset_key* rrset, - struct ub_packed_rrset_key* dnskey, char** reason); + struct ub_packed_rrset_key* dnskey, int downprot, char** reason); /** * verify rrset against one specific dnskey (from rrset) diff --git a/validator/val_utils.c b/validator/val_utils.c index 7539b815f..9dfafb21a 100644 --- a/validator/val_utils.c +++ b/validator/val_utils.c @@ -310,7 +310,7 @@ rrset_get_ttl(struct ub_packed_rrset_key* rrset) enum sec_status val_verify_rrset(struct module_env* env, struct val_env* ve, struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* keys, - char** reason) + int downprot, char** reason) { enum sec_status sec; struct packed_rrset_data* d = (struct packed_rrset_data*)rrset-> @@ -332,7 +332,7 @@ val_verify_rrset(struct module_env* env, struct val_env* ve, } log_nametypeclass(VERB_ALGO, "verify rrset", rrset->rk.dname, ntohs(rrset->rk.type), ntohs(rrset->rk.rrset_class)); - sec = dnskeyset_verify_rrset(env, ve, rrset, keys, reason); + sec = dnskeyset_verify_rrset(env, ve, rrset, keys, downprot, reason); verbose(VERB_ALGO, "verify result: %s", sec_status_to_string(sec)); regional_free_all(env->scratch); @@ -378,7 +378,7 @@ val_verify_rrset_entry(struct module_env* env, struct val_env* ve, dnskey.rk.dname_len = kkey->namelen; dnskey.entry.key = &dnskey; dnskey.entry.data = kd->rrset_data; - sec = val_verify_rrset(env, ve, rrset, &dnskey, reason); + sec = val_verify_rrset(env, ve, rrset, &dnskey, 1, reason); return sec; } @@ -453,7 +453,7 @@ int val_favorite_ds_algo(struct ub_packed_rrset_key* ds_rrset) enum sec_status val_verify_DNSKEY_with_DS(struct module_env* env, struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset, - struct ub_packed_rrset_key* ds_rrset, char** reason) + struct ub_packed_rrset_key* ds_rrset, int downprot, char** reason) { /* as long as this is false, we can consider this DS rrset to be * equivalent to no DS rrset. */ @@ -472,7 +472,8 @@ val_verify_DNSKEY_with_DS(struct module_env* env, struct val_env* ve, } digest_algo = val_favorite_ds_algo(ds_rrset); - algo_needs_init_ds(&needs, ds_rrset, digest_algo); + if(downprot) + algo_needs_init_ds(&needs, ds_rrset, digest_algo); num = rrset_get_count(ds_rrset); for(i=0; ids_rrset) { kkey = val_verify_new_DNSKEYs(qstate->region, qstate->env, ve, - dnskey_rrset, ta->ds_rrset, &reason); + dnskey_rrset, ta->ds_rrset, 0, &reason); if(!kkey) { log_err("out of memory: verifying prime DS"); return NULL; @@ -2260,7 +2260,7 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset, } if(sec != sec_status_secure && ta->dnskey_rrset) { sec = val_verify_rrset(qstate->env, ve, dnskey_rrset, - ta->dnskey_rrset, &reason); + ta->dnskey_rrset, 0, &reason); verbose(VERB_DETAIL, "validate keys with anchor(DNSKEY): %s", sec_status_to_string(sec)); if(sec == sec_status_secure) { @@ -2614,6 +2614,7 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq, struct val_env* ve = (struct val_env*)qstate->env->modinfo[id]; struct key_entry_key* old = vq->key_entry; struct ub_packed_rrset_key* dnskey = NULL; + int downprot; char* reason = NULL; if(rcode == LDNS_RCODE_NOERROR) @@ -2649,8 +2650,10 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq, vq->state = VAL_VALIDATE_STATE; return; } + /* protect DS against downgrade, but DLV does not(for key scrapers) */ + downprot = (ntohs(vq->ds_rrset->rk.type) == LDNS_RR_TYPE_DS); vq->key_entry = val_verify_new_DNSKEYs(qstate->region, qstate->env, - ve, dnskey, vq->ds_rrset, &reason); + ve, dnskey, vq->ds_rrset, downprot, &reason); if(!vq->key_entry) { log_err("out of memory in verify new DNSKEYs");