]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Algorithm rollover operational reality intrudes, for trust-anchor,
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 16 Sep 2010 13:40:26 +0000 (13:40 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 16 Sep 2010 13:40:26 +0000 (13:40 +0000)
         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

doc/Changelog
testcode/unitverify.c
testdata/val_ta_algo_dnskey.rpl [new file with mode: 0644]
testdata/val_ta_algo_ds.rpl [new file with mode: 0644]
validator/autotrust.c
validator/val_sigcrypt.c
validator/val_sigcrypt.h
validator/val_utils.c
validator/val_utils.h
validator/validator.c

index 8d4a5ce5137a44fa565264c4f9ce6f1f5752c75f..bc7dc9b69ae4d271c54dd8b64200cd82329b0528 100644 (file)
@@ -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.
 
index 4679cef8d76d43c38ef7125f098a90d2427d5496..ba5180e55ae2f995f449713e86a5ef052e112372 100644 (file)
@@ -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 (file)
index 0000000..f98f8b1
--- /dev/null
@@ -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 (file)
index 0000000..4f66a02
--- /dev/null
@@ -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
index f31f627920b9ef4dd5c054647fea00d647621aa0..e43d94166a84a8be4874fc52be7f0fe3b09e25c6 100644 (file)
@@ -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) {
index 25790f58302396db1273ea32bec100ae7c318918..1fe63c115d5319d2e6ea218f28760322cd5b3305 100644 (file)
@@ -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;
index 3ced1e75a9e8c7f3a84d920c78971b0e4abec2c1..d021e8b63115ec252c7ca7d6528e84b2e2d2a9d2 100644 (file)
@@ -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) 
index 7539b815f2d1f3129f40f361469a309d030b682b..9dfafb21a4b6444a81aac26be5fd24a50e7473bd 100644 (file)
@@ -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; i<num; i++) {
                /* Check to see if we can understand this DS. 
@@ -491,12 +492,12 @@ val_verify_DNSKEY_with_DS(struct module_env* env, struct val_env* ve,
                sec = verify_dnskeys_with_ds_rr(env, ve, dnskey_rrset, 
                        ds_rrset, i, reason);
                if(sec == sec_status_secure) {
-                       if(algo_needs_set_secure(&needs,
+                       if(!downprot || algo_needs_set_secure(&needs,
                                (uint8_t)ds_get_key_algo(ds_rrset, i))) {
                                verbose(VERB_ALGO, "DS matched DNSKEY.");
                                return sec_status_secure;
                        }
-               } else if(sec == sec_status_bogus) {
+               } else if(downprot && sec == sec_status_bogus) {
                        algo_needs_set_bogus(&needs,
                                (uint8_t)ds_get_key_algo(ds_rrset, i));
                }
@@ -512,7 +513,7 @@ val_verify_DNSKEY_with_DS(struct module_env* env, struct val_env* ve,
        }
        /* If any were understandable, then it is bad. */
        verbose(VERB_QUERY, "Failed to match any usable DS to a DNSKEY.");
-       if((alg=algo_needs_missing(&needs)) != 0) {
+       if(downprot && (alg=algo_needs_missing(&needs)) != 0) {
                algo_needs_reason(env, alg, reason, "missing verification of "
                        "DNSKEY signature");
        }
@@ -522,10 +523,10 @@ val_verify_DNSKEY_with_DS(struct module_env* env, struct val_env* ve,
 struct key_entry_key* 
 val_verify_new_DNSKEYs(struct regional* region, 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)
 {
        enum sec_status sec = val_verify_DNSKEY_with_DS(env, ve, 
-               dnskey_rrset, ds_rrset, reason);
+               dnskey_rrset, ds_rrset, downprot, reason);
 
        if(sec == sec_status_secure) {
                return key_entry_create_rrset(region, 
index 7340c4bd1a08c65e910fd008306277c1696bdf68..a5bc6c9adc96d4b3a9e49399614b2ad6ea155339 100644 (file)
@@ -117,12 +117,14 @@ void val_find_signer(enum val_classification subtype,
  * @param ve: validator environment (verification settings)
  * @param rrset: what to verify
  * @param keys: dnskey rrset to verify with.
+ * @param downprot: if true provide downgrade protection otherwise one
+ *   algorithm is enough.
  * @param reason: reason of failure. Fixed string or alloced in scratch.
  * @return security status of verification.
  */
 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);
 
 /**
  * Verify RRset with keys from a keyset.
@@ -144,6 +146,8 @@ enum sec_status val_verify_rrset_entry(struct module_env* env,
  * @param ve: validator environment (verification settings)
  * @param dnskey_rrset: DNSKEY rrset to verify
  * @param ds_rrset: DS rrset to verify with.
+ * @param downprot: if true provide downgrade protection otherwise one
+ *   algorithm is enough.
  * @param reason: reason of failure. Fixed string or alloced in scratch.
  * @return: sec_status_secure if a DS matches.
  *     sec_status_insecure if end of trust (i.e., unknown algorithms).
@@ -151,7 +155,7 @@ enum sec_status val_verify_rrset_entry(struct module_env* env,
  */
 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);
 
 /**
  * Verify new DNSKEYs with DS rrset. The DS contains hash values that should
@@ -163,6 +167,8 @@ enum sec_status val_verify_DNSKEY_with_DS(struct module_env* env,
  * @param ve: validator environment (verification settings)
  * @param dnskey_rrset: DNSKEY rrset to verify
  * @param ds_rrset: DS rrset to verify with.
+ * @param downprot: if true provide downgrade protection otherwise one
+ *   algorithm is enough.
  * @param reason: reason of failure. Fixed string or alloced in scratch.
  * @return a KeyEntry. This will either contain the now trusted
  *         dnskey_rrset, a "null" key entry indicating that this DS
@@ -176,7 +182,7 @@ enum sec_status val_verify_DNSKEY_with_DS(struct module_env* env,
 struct key_entry_key* val_verify_new_DNSKEYs(struct regional* region, 
        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);
 
 /**
  * Determine if DS rrset is usable for validator or not.
index ce6d71b4d10024c2b44d6de4024504c5c6b6e19f..5443e4fa5dc53b154a4d9c8ad94dcbeb9571e9ac 100644 (file)
@@ -2246,7 +2246,7 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
        /* attempt to verify with trust anchor DS and DNSKEY */
        if(ta->ds_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");