New upstream version 1.6.8
Robert Edmonds
6 years ago
0 | # generated automatically by aclocal 1.15 -*- Autoconf -*- | |
1 | ||
2 | # Copyright (C) 1996-2014 Free Software Foundation, Inc. | |
0 | # generated automatically by aclocal 1.15.1 -*- Autoconf -*- | |
1 | ||
2 | # Copyright (C) 1996-2017 Free Software Foundation, Inc. | |
3 | 3 | |
4 | 4 | # This file is free software; the Free Software Foundation |
5 | 5 | # gives unlimited permission to copy and/or distribute it, |
9389 | 9389 | |
9390 | 9390 | # AM_CONDITIONAL -*- Autoconf -*- |
9391 | 9391 | |
9392 | # Copyright (C) 1997-2014 Free Software Foundation, Inc. | |
9392 | # Copyright (C) 1997-2017 Free Software Foundation, Inc. | |
9393 | 9393 | # |
9394 | 9394 | # This file is free software; the Free Software Foundation |
9395 | 9395 | # gives unlimited permission to copy and/or distribute it, |
9420 | 9420 | Usually this means the macro was only invoked conditionally.]]) |
9421 | 9421 | fi])]) |
9422 | 9422 | |
9423 | # Copyright (C) 2006-2014 Free Software Foundation, Inc. | |
9423 | # Copyright (C) 2006-2017 Free Software Foundation, Inc. | |
9424 | 9424 | # |
9425 | 9425 | # This file is free software; the Free Software Foundation |
9426 | 9426 | # gives unlimited permission to copy and/or distribute it, |
0 | 0 | #! /bin/sh |
1 | 1 | # Guess values for system-dependent variables and create Makefiles. |
2 | # Generated by GNU Autoconf 2.69 for unbound 1.6.7. | |
2 | # Generated by GNU Autoconf 2.69 for unbound 1.6.8. | |
3 | 3 | # |
4 | 4 | # Report bugs to <unbound-bugs@nlnetlabs.nl>. |
5 | 5 | # |
589 | 589 | # Identity of this package. |
590 | 590 | PACKAGE_NAME='unbound' |
591 | 591 | PACKAGE_TARNAME='unbound' |
592 | PACKAGE_VERSION='1.6.7' | |
593 | PACKAGE_STRING='unbound 1.6.7' | |
592 | PACKAGE_VERSION='1.6.8' | |
593 | PACKAGE_STRING='unbound 1.6.8' | |
594 | 594 | PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl' |
595 | 595 | PACKAGE_URL='' |
596 | 596 | |
1436 | 1436 | # Omit some internal or obsolete options to make the list less imposing. |
1437 | 1437 | # This message is too long to be a string in the A/UX 3.1 sh. |
1438 | 1438 | cat <<_ACEOF |
1439 | \`configure' configures unbound 1.6.7 to adapt to many kinds of systems. | |
1439 | \`configure' configures unbound 1.6.8 to adapt to many kinds of systems. | |
1440 | 1440 | |
1441 | 1441 | Usage: $0 [OPTION]... [VAR=VALUE]... |
1442 | 1442 | |
1501 | 1501 | |
1502 | 1502 | if test -n "$ac_init_help"; then |
1503 | 1503 | case $ac_init_help in |
1504 | short | recursive ) echo "Configuration of unbound 1.6.7:";; | |
1504 | short | recursive ) echo "Configuration of unbound 1.6.8:";; | |
1505 | 1505 | esac |
1506 | 1506 | cat <<\_ACEOF |
1507 | 1507 | |
1713 | 1713 | test -n "$ac_init_help" && exit $ac_status |
1714 | 1714 | if $ac_init_version; then |
1715 | 1715 | cat <<\_ACEOF |
1716 | unbound configure 1.6.7 | |
1716 | unbound configure 1.6.8 | |
1717 | 1717 | generated by GNU Autoconf 2.69 |
1718 | 1718 | |
1719 | 1719 | Copyright (C) 2012 Free Software Foundation, Inc. |
2422 | 2422 | This file contains any messages produced by compilers while |
2423 | 2423 | running configure, to aid debugging if configure makes a mistake. |
2424 | 2424 | |
2425 | It was created by unbound $as_me 1.6.7, which was | |
2425 | It was created by unbound $as_me 1.6.8, which was | |
2426 | 2426 | generated by GNU Autoconf 2.69. Invocation command line was |
2427 | 2427 | |
2428 | 2428 | $ $0 $@ |
2774 | 2774 | |
2775 | 2775 | UNBOUND_VERSION_MINOR=6 |
2776 | 2776 | |
2777 | UNBOUND_VERSION_MICRO=7 | |
2777 | UNBOUND_VERSION_MICRO=8 | |
2778 | 2778 | |
2779 | 2779 | |
2780 | 2780 | LIBUNBOUND_CURRENT=7 |
2781 | LIBUNBOUND_REVISION=6 | |
2781 | LIBUNBOUND_REVISION=7 | |
2782 | 2782 | LIBUNBOUND_AGE=5 |
2783 | 2783 | # 1.0.0 had 0:12:0 |
2784 | 2784 | # 1.0.1 had 0:13:0 |
2836 | 2836 | # 1.6.5 had 7:4:5 |
2837 | 2837 | # 1.6.6 had 7:5:5 |
2838 | 2838 | # 1.6.7 had 7:6:5 |
2839 | # 1.6.8 had 7:7:5 | |
2839 | 2840 | |
2840 | 2841 | # Current -- the number of the binary API that we're implementing |
2841 | 2842 | # Revision -- which iteration of the implementation of the binary |
20693 | 20694 | |
20694 | 20695 | |
20695 | 20696 | |
20696 | version=1.6.7 | |
20697 | version=1.6.8 | |
20697 | 20698 | |
20698 | 20699 | date=`date +'%b %e, %Y'` |
20699 | 20700 | |
21212 | 21213 | # report actual input values of CONFIG_FILES etc. instead of their |
21213 | 21214 | # values after options handling. |
21214 | 21215 | ac_log=" |
21215 | This file was extended by unbound $as_me 1.6.7, which was | |
21216 | This file was extended by unbound $as_me 1.6.8, which was | |
21216 | 21217 | generated by GNU Autoconf 2.69. Invocation command line was |
21217 | 21218 | |
21218 | 21219 | CONFIG_FILES = $CONFIG_FILES |
21278 | 21279 | cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 |
21279 | 21280 | ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" |
21280 | 21281 | ac_cs_version="\\ |
21281 | unbound config.status 1.6.7 | |
21282 | unbound config.status 1.6.8 | |
21282 | 21283 | configured by $0, generated by GNU Autoconf 2.69, |
21283 | 21284 | with options \\"\$ac_cs_config\\" |
21284 | 21285 |
10 | 10 | # must be numbers. ac_defun because of later processing |
11 | 11 | m4_define([VERSION_MAJOR],[1]) |
12 | 12 | m4_define([VERSION_MINOR],[6]) |
13 | m4_define([VERSION_MICRO],[7]) | |
13 | m4_define([VERSION_MICRO],[8]) | |
14 | 14 | AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl, unbound) |
15 | 15 | AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR]) |
16 | 16 | AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR]) |
17 | 17 | AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO]) |
18 | 18 | |
19 | 19 | LIBUNBOUND_CURRENT=7 |
20 | LIBUNBOUND_REVISION=6 | |
20 | LIBUNBOUND_REVISION=7 | |
21 | 21 | LIBUNBOUND_AGE=5 |
22 | 22 | # 1.0.0 had 0:12:0 |
23 | 23 | # 1.0.1 had 0:13:0 |
75 | 75 | # 1.6.5 had 7:4:5 |
76 | 76 | # 1.6.6 had 7:5:5 |
77 | 77 | # 1.6.7 had 7:6:5 |
78 | # 1.6.8 had 7:7:5 | |
78 | 79 | |
79 | 80 | # Current -- the number of the binary API that we're implementing |
80 | 81 | # Revision -- which iteration of the implementation of the binary |
0 | 19 January 2018: Wouter | |
1 | - patch for CVE-2017-15105: vulnerability in the processing of | |
2 | wildcard synthesized NSEC records. | |
3 | ||
0 | 4 | 10 October 2017: Wouter |
1 | 5 | - tag 1.6.7 |
2 | 6 |
0 | README for Unbound 1.6.7 | |
0 | README for Unbound 1.6.8 | |
1 | 1 | Copyright 2007 NLnet Labs |
2 | 2 | http://unbound.net |
3 | 3 |
0 | 0 | # |
1 | 1 | # Example configuration file. |
2 | 2 | # |
3 | # See unbound.conf(5) man page, version 1.6.7. | |
3 | # See unbound.conf(5) man page, version 1.6.8. | |
4 | 4 | # |
5 | 5 | # this is a comment. |
6 | 6 |
0 | .TH "libunbound" "3" "Oct 10, 2017" "NLnet Labs" "unbound 1.6.7" | |
0 | .TH "libunbound" "3" "Jan 19, 2018" "NLnet Labs" "unbound 1.6.8" | |
1 | 1 | .\" |
2 | 2 | .\" libunbound.3 -- unbound library functions manual |
3 | 3 | .\" |
42 | 42 | .B ub_ctx_zone_remove, |
43 | 43 | .B ub_ctx_data_add, |
44 | 44 | .B ub_ctx_data_remove |
45 | \- Unbound DNS validating resolver 1.6.7 functions. | |
45 | \- Unbound DNS validating resolver 1.6.8 functions. | |
46 | 46 | .SH "SYNOPSIS" |
47 | 47 | .B #include <unbound.h> |
48 | 48 | .LP |
0 | .TH "unbound-anchor" "8" "Oct 10, 2017" "NLnet Labs" "unbound 1.6.7" | |
0 | .TH "unbound-anchor" "8" "Jan 19, 2018" "NLnet Labs" "unbound 1.6.8" | |
1 | 1 | .\" |
2 | 2 | .\" unbound-anchor.8 -- unbound anchor maintenance utility manual |
3 | 3 | .\" |
0 | .TH "unbound-checkconf" "8" "Oct 10, 2017" "NLnet Labs" "unbound 1.6.7" | |
0 | .TH "unbound-checkconf" "8" "Jan 19, 2018" "NLnet Labs" "unbound 1.6.8" | |
1 | 1 | .\" |
2 | 2 | .\" unbound-checkconf.8 -- unbound configuration checker manual |
3 | 3 | .\" |
0 | .TH "unbound-control" "8" "Oct 10, 2017" "NLnet Labs" "unbound 1.6.7" | |
0 | .TH "unbound-control" "8" "Jan 19, 2018" "NLnet Labs" "unbound 1.6.8" | |
1 | 1 | .\" |
2 | 2 | .\" unbound-control.8 -- unbound remote control manual |
3 | 3 | .\" |
0 | .TH "unbound\-host" "1" "Oct 10, 2017" "NLnet Labs" "unbound 1.6.7" | |
0 | .TH "unbound\-host" "1" "Jan 19, 2018" "NLnet Labs" "unbound 1.6.8" | |
1 | 1 | .\" |
2 | 2 | .\" unbound-host.1 -- unbound DNS lookup utility |
3 | 3 | .\" |
0 | .TH "unbound" "8" "Oct 10, 2017" "NLnet Labs" "unbound 1.6.7" | |
0 | .TH "unbound" "8" "Jan 19, 2018" "NLnet Labs" "unbound 1.6.8" | |
1 | 1 | .\" |
2 | 2 | .\" unbound.8 -- unbound manual |
3 | 3 | .\" |
8 | 8 | .\" |
9 | 9 | .SH "NAME" |
10 | 10 | .B unbound |
11 | \- Unbound DNS validating resolver 1.6.7. | |
11 | \- Unbound DNS validating resolver 1.6.8. | |
12 | 12 | .SH "SYNOPSIS" |
13 | 13 | .B unbound |
14 | 14 | .RB [ \-h ] |
0 | .TH "unbound.conf" "5" "Oct 10, 2017" "NLnet Labs" "unbound 1.6.7" | |
0 | .TH "unbound.conf" "5" "Jan 19, 2018" "NLnet Labs" "unbound 1.6.8" | |
1 | 1 | .\" |
2 | 2 | .\" unbound.conf.5 -- unbound.conf manual |
3 | 3 | .\" |
185 | 185 | ntohs(rrset->rk.rrset_class)); |
186 | 186 | } |
187 | 187 | setup_sigalg(dnskey, sigalg); /* check all algorithms in the dnskey */ |
188 | sec = dnskeyset_verify_rrset(env, ve, rrset, dnskey, sigalg, &reason); | |
188 | /* ok to give null as qstate here, won't be used for answer section. */ | |
189 | sec = dnskeyset_verify_rrset(env, ve, rrset, dnskey, sigalg, &reason, | |
190 | LDNS_SECTION_ANSWER, NULL); | |
189 | 191 | if(vsig) { |
190 | 192 | printf("verify outcome is: %s %s\n", sec_status_to_string(sec), |
191 | 193 | reason?reason:""); |
1226 | 1226 | * @param ve: validator environment (with options) for verification. |
1227 | 1227 | * @param tp: trust point to verify with |
1228 | 1228 | * @param rrset: DNSKEY rrset to verify. |
1229 | * @param qstate: qstate with region. | |
1229 | 1230 | * @return false on failure, true if verification successful. |
1230 | 1231 | */ |
1231 | 1232 | static int |
1232 | 1233 | verify_dnskey(struct module_env* env, struct val_env* ve, |
1233 | struct trust_anchor* tp, struct ub_packed_rrset_key* rrset) | |
1234 | struct trust_anchor* tp, struct ub_packed_rrset_key* rrset, | |
1235 | struct module_qstate* qstate) | |
1234 | 1236 | { |
1235 | 1237 | char* reason = NULL; |
1236 | 1238 | uint8_t sigalg[ALGO_NEEDS_MAX+1]; |
1237 | 1239 | int downprot = env->cfg->harden_algo_downgrade; |
1238 | 1240 | enum sec_status sec = val_verify_DNSKEY_with_TA(env, ve, rrset, |
1239 | tp->ds_rrset, tp->dnskey_rrset, downprot?sigalg:NULL, &reason); | |
1241 | tp->ds_rrset, tp->dnskey_rrset, downprot?sigalg:NULL, &reason, | |
1242 | qstate); | |
1240 | 1243 | /* sigalg is ignored, it returns algorithms signalled to exist, but |
1241 | 1244 | * in 5011 there are no other rrsets to check. if downprot is |
1242 | 1245 | * enabled, then it checks that the DNSKEY is signed with all |
1275 | 1278 | /** Is rr self-signed revoked key */ |
1276 | 1279 | static int |
1277 | 1280 | rr_is_selfsigned_revoked(struct module_env* env, struct val_env* ve, |
1278 | struct ub_packed_rrset_key* dnskey_rrset, size_t i) | |
1281 | struct ub_packed_rrset_key* dnskey_rrset, size_t i, | |
1282 | struct module_qstate* qstate) | |
1279 | 1283 | { |
1280 | 1284 | enum sec_status sec; |
1281 | 1285 | char* reason = NULL; |
1284 | 1288 | /* no algorithm downgrade protection necessary, if it is selfsigned |
1285 | 1289 | * revoked it can be removed. */ |
1286 | 1290 | sec = dnskey_verify_rrset(env, ve, dnskey_rrset, dnskey_rrset, i, |
1287 | &reason); | |
1291 | &reason, LDNS_SECTION_ANSWER, qstate); | |
1288 | 1292 | return (sec == sec_status_secure); |
1289 | 1293 | } |
1290 | 1294 | |
1500 | 1504 | static void |
1501 | 1505 | check_contains_revoked(struct module_env* env, struct val_env* ve, |
1502 | 1506 | struct trust_anchor* tp, struct ub_packed_rrset_key* dnskey_rrset, |
1503 | int* changed) | |
1507 | int* changed, struct module_qstate* qstate) | |
1504 | 1508 | { |
1505 | 1509 | struct packed_rrset_data* dd = (struct packed_rrset_data*) |
1506 | 1510 | dnskey_rrset->entry.data; |
1520 | 1524 | } |
1521 | 1525 | if(!ta) |
1522 | 1526 | continue; /* key not found */ |
1523 | if(rr_is_selfsigned_revoked(env, ve, dnskey_rrset, i)) { | |
1527 | if(rr_is_selfsigned_revoked(env, ve, dnskey_rrset, i, qstate)) { | |
1524 | 1528 | /* checked if there is an rrsig signed by this key. */ |
1525 | 1529 | /* same keytag, but stored can be revoked already, so |
1526 | 1530 | * compare keytags, with +0 or +128(REVOKE flag) */ |
2117 | 2121 | } |
2118 | 2122 | |
2119 | 2123 | int autr_process_prime(struct module_env* env, struct val_env* ve, |
2120 | struct trust_anchor* tp, struct ub_packed_rrset_key* dnskey_rrset) | |
2124 | struct trust_anchor* tp, struct ub_packed_rrset_key* dnskey_rrset, | |
2125 | struct module_qstate* qstate) | |
2121 | 2126 | { |
2122 | 2127 | int changed = 0; |
2123 | 2128 | log_assert(tp && tp->autr); |
2158 | 2163 | return 1; /* trust point exists */ |
2159 | 2164 | } |
2160 | 2165 | /* check for revoked keys to remove immediately */ |
2161 | check_contains_revoked(env, ve, tp, dnskey_rrset, &changed); | |
2166 | check_contains_revoked(env, ve, tp, dnskey_rrset, &changed, qstate); | |
2162 | 2167 | if(changed) { |
2163 | 2168 | verbose(VERB_ALGO, "autotrust: revokedkeys, reassemble"); |
2164 | 2169 | if(!autr_assemble(tp)) { |
2174 | 2179 | } |
2175 | 2180 | } |
2176 | 2181 | /* verify the dnskey rrset and see if it is valid. */ |
2177 | if(!verify_dnskey(env, ve, tp, dnskey_rrset)) { | |
2182 | if(!verify_dnskey(env, ve, tp, dnskey_rrset, qstate)) { | |
2178 | 2183 | verbose(VERB_ALGO, "autotrust: dnskey did not verify."); |
2179 | 2184 | /* only increase failure count if this is not the first prime, |
2180 | 2185 | * this means there was a previous successful probe */ |
46 | 46 | struct trust_anchor; |
47 | 47 | struct ub_packed_rrset_key; |
48 | 48 | struct module_env; |
49 | struct module_qstate; | |
49 | 50 | struct val_env; |
50 | 51 | struct sldns_buffer; |
51 | 52 | |
187 | 188 | * @param tp: trust anchor to process. |
188 | 189 | * @param dnskey_rrset: DNSKEY rrset probed (can be NULL if bad prime result). |
189 | 190 | * allocated in a region. Has not been validated yet. |
191 | * @param qstate: qstate with region. | |
190 | 192 | * @return false if trust anchor was revoked completely. |
191 | 193 | * Otherwise logs errors to log, does not change return value. |
192 | 194 | * On errors, likely the trust point has been unchanged. |
193 | 195 | */ |
194 | 196 | int autr_process_prime(struct module_env* env, struct val_env* ve, |
195 | struct trust_anchor* tp, struct ub_packed_rrset_key* dnskey_rrset); | |
197 | struct trust_anchor* tp, struct ub_packed_rrset_key* dnskey_rrset, | |
198 | struct module_qstate* qstate); | |
196 | 199 | |
197 | 200 | /** |
198 | 201 | * Debug printout of rfc5011 tracked anchors |
175 | 175 | static int |
176 | 176 | nsec_verify_rrset(struct module_env* env, struct val_env* ve, |
177 | 177 | struct ub_packed_rrset_key* nsec, struct key_entry_key* kkey, |
178 | char** reason) | |
178 | char** reason, struct module_qstate* qstate) | |
179 | 179 | { |
180 | 180 | struct packed_rrset_data* d = (struct packed_rrset_data*) |
181 | 181 | nsec->entry.data; |
184 | 184 | rrset_check_sec_status(env->rrset_cache, nsec, *env->now); |
185 | 185 | if(d->security == sec_status_secure) |
186 | 186 | return 1; |
187 | d->security = val_verify_rrset_entry(env, ve, nsec, kkey, reason); | |
187 | d->security = val_verify_rrset_entry(env, ve, nsec, kkey, reason, | |
188 | LDNS_SECTION_AUTHORITY, qstate); | |
188 | 189 | if(d->security == sec_status_secure) { |
189 | 190 | rrset_update_sec_status(env->rrset_cache, nsec, *env->now); |
190 | 191 | return 1; |
195 | 196 | enum sec_status |
196 | 197 | val_nsec_prove_nodata_dsreply(struct module_env* env, struct val_env* ve, |
197 | 198 | struct query_info* qinfo, struct reply_info* rep, |
198 | struct key_entry_key* kkey, time_t* proof_ttl, char** reason) | |
199 | struct key_entry_key* kkey, time_t* proof_ttl, char** reason, | |
200 | struct module_qstate* qstate) | |
199 | 201 | { |
200 | 202 | struct ub_packed_rrset_key* nsec = reply_find_rrset_section_ns( |
201 | 203 | rep, qinfo->qname, qinfo->qname_len, LDNS_RR_TYPE_NSEC, |
212 | 214 | * 1) this is a delegation point and there is no DS |
213 | 215 | * 2) this is not a delegation point */ |
214 | 216 | if(nsec) { |
215 | if(!nsec_verify_rrset(env, ve, nsec, kkey, reason)) { | |
217 | if(!nsec_verify_rrset(env, ve, nsec, kkey, reason, qstate)) { | |
216 | 218 | verbose(VERB_ALGO, "NSEC RRset for the " |
217 | 219 | "referral did not verify."); |
218 | 220 | return sec_status_bogus; |
241 | 243 | i++) { |
242 | 244 | if(rep->rrsets[i]->rk.type != htons(LDNS_RR_TYPE_NSEC)) |
243 | 245 | continue; |
244 | if(!nsec_verify_rrset(env, ve, rep->rrsets[i], kkey, reason)) { | |
246 | if(!nsec_verify_rrset(env, ve, rep->rrsets[i], kkey, reason, | |
247 | qstate)) { | |
245 | 248 | verbose(VERB_ALGO, "NSEC for empty non-terminal " |
246 | 249 | "did not verify."); |
247 | 250 | return sec_status_bogus; |
45 | 45 | #include "util/data/packed_rrset.h" |
46 | 46 | struct val_env; |
47 | 47 | struct module_env; |
48 | struct module_qstate; | |
48 | 49 | struct ub_packed_rrset_key; |
49 | 50 | struct reply_info; |
50 | 51 | struct query_info; |
63 | 64 | * @param kkey: key entry to use for verification of signatures. |
64 | 65 | * @param proof_ttl: if secure, the TTL of how long this proof lasts. |
65 | 66 | * @param reason: string explaining why bogus. |
67 | * @param qstate: qstate with region. | |
66 | 68 | * @return security status. |
67 | 69 | * SECURE: proved absence of DS. |
68 | 70 | * INSECURE: proved that this was not a delegation point. |
72 | 74 | enum sec_status val_nsec_prove_nodata_dsreply(struct module_env* env, |
73 | 75 | struct val_env* ve, struct query_info* qinfo, |
74 | 76 | struct reply_info* rep, struct key_entry_key* kkey, |
75 | time_t* proof_ttl, char** reason); | |
77 | time_t* proof_ttl, char** reason, struct module_qstate* qstate); | |
76 | 78 | |
77 | 79 | /** |
78 | 80 | * nsec typemap check, takes an NSEC-type bitmap as argument, checks for type. |
1284 | 1284 | static int |
1285 | 1285 | list_is_secure(struct module_env* env, struct val_env* ve, |
1286 | 1286 | struct ub_packed_rrset_key** list, size_t num, |
1287 | struct key_entry_key* kkey, char** reason) | |
1287 | struct key_entry_key* kkey, char** reason, struct module_qstate* qstate) | |
1288 | 1288 | { |
1289 | 1289 | struct packed_rrset_data* d; |
1290 | 1290 | size_t i; |
1298 | 1298 | if(d->security == sec_status_secure) |
1299 | 1299 | continue; |
1300 | 1300 | d->security = val_verify_rrset_entry(env, ve, list[i], kkey, |
1301 | reason); | |
1301 | reason, LDNS_SECTION_AUTHORITY, qstate); | |
1302 | 1302 | if(d->security != sec_status_secure) { |
1303 | 1303 | verbose(VERB_ALGO, "NSEC3 did not verify"); |
1304 | 1304 | return 0; |
1311 | 1311 | enum sec_status |
1312 | 1312 | nsec3_prove_nods(struct module_env* env, struct val_env* ve, |
1313 | 1313 | struct ub_packed_rrset_key** list, size_t num, |
1314 | struct query_info* qinfo, struct key_entry_key* kkey, char** reason) | |
1314 | struct query_info* qinfo, struct key_entry_key* kkey, char** reason, | |
1315 | struct module_qstate* qstate) | |
1315 | 1316 | { |
1316 | 1317 | rbtree_type ct; |
1317 | 1318 | struct nsec3_filter flt; |
1324 | 1325 | *reason = "no valid NSEC3s"; |
1325 | 1326 | return sec_status_bogus; /* no valid NSEC3s, bogus */ |
1326 | 1327 | } |
1327 | if(!list_is_secure(env, ve, list, num, kkey, reason)) | |
1328 | if(!list_is_secure(env, ve, list, num, kkey, reason, qstate)) | |
1328 | 1329 | return sec_status_bogus; /* not all NSEC3 records secure */ |
1329 | 1330 | rbtree_init(&ct, &nsec3_hash_cmp); /* init names-to-hash cache */ |
1330 | 1331 | filter_init(&flt, list, num, qinfo); /* init RR iterator */ |
70 | 70 | struct val_env; |
71 | 71 | struct regional; |
72 | 72 | struct module_env; |
73 | struct module_qstate; | |
73 | 74 | struct ub_packed_rrset_key; |
74 | 75 | struct reply_info; |
75 | 76 | struct query_info; |
184 | 185 | * @param qinfo: query that is verified for. |
185 | 186 | * @param kkey: key entry that signed the NSEC3s. |
186 | 187 | * @param reason: string for bogus result. |
188 | * @param qstate: qstate with region. | |
187 | 189 | * @return: |
188 | 190 | * sec_status SECURE of the proposition is proven by the NSEC3 RRs, |
189 | 191 | * BOGUS if not, INSECURE if all of the NSEC3s could be validly ignored. |
193 | 195 | enum sec_status |
194 | 196 | nsec3_prove_nods(struct module_env* env, struct val_env* ve, |
195 | 197 | struct ub_packed_rrset_key** list, size_t num, |
196 | struct query_info* qinfo, struct key_entry_key* kkey, char** reason); | |
198 | struct query_info* qinfo, struct key_entry_key* kkey, char** reason, | |
199 | struct module_qstate* qstate); | |
197 | 200 | |
198 | 201 | /** |
199 | 202 | * Prove NXDOMAIN or NODATA. |
484 | 484 | enum sec_status |
485 | 485 | dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve, |
486 | 486 | struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey, |
487 | uint8_t* sigalg, char** reason) | |
487 | uint8_t* sigalg, char** reason, sldns_pkt_section section, | |
488 | struct module_qstate* qstate) | |
488 | 489 | { |
489 | 490 | enum sec_status sec; |
490 | 491 | size_t i, num; |
511 | 512 | } |
512 | 513 | for(i=0; i<num; i++) { |
513 | 514 | sec = dnskeyset_verify_rrset_sig(env, ve, *env->now, rrset, |
514 | dnskey, i, &sortree, reason); | |
515 | dnskey, i, &sortree, reason, section, qstate); | |
515 | 516 | /* see which algorithm has been fixed up */ |
516 | 517 | if(sec == sec_status_secure) { |
517 | 518 | if(!sigalg) |
552 | 553 | enum sec_status |
553 | 554 | dnskey_verify_rrset(struct module_env* env, struct val_env* ve, |
554 | 555 | struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey, |
555 | size_t dnskey_idx, char** reason) | |
556 | size_t dnskey_idx, char** reason, sldns_pkt_section section, | |
557 | struct module_qstate* qstate) | |
556 | 558 | { |
557 | 559 | enum sec_status sec; |
558 | 560 | size_t i, num, numchecked = 0; |
576 | 578 | buf_canon = 0; |
577 | 579 | sec = dnskey_verify_rrset_sig(env->scratch, |
578 | 580 | env->scratch_buffer, ve, *env->now, rrset, |
579 | dnskey, dnskey_idx, i, &sortree, &buf_canon, reason); | |
581 | dnskey, dnskey_idx, i, &sortree, &buf_canon, reason, | |
582 | section, qstate); | |
580 | 583 | if(sec == sec_status_secure) |
581 | 584 | return sec; |
582 | 585 | numchecked ++; |
590 | 593 | dnskeyset_verify_rrset_sig(struct module_env* env, struct val_env* ve, |
591 | 594 | time_t now, struct ub_packed_rrset_key* rrset, |
592 | 595 | struct ub_packed_rrset_key* dnskey, size_t sig_idx, |
593 | struct rbtree_type** sortree, char** reason) | |
596 | struct rbtree_type** sortree, char** reason, sldns_pkt_section section, | |
597 | struct module_qstate* qstate) | |
594 | 598 | { |
595 | 599 | /* find matching keys and check them */ |
596 | 600 | enum sec_status sec = sec_status_bogus; |
615 | 619 | /* see if key verifies */ |
616 | 620 | sec = dnskey_verify_rrset_sig(env->scratch, |
617 | 621 | env->scratch_buffer, ve, now, rrset, dnskey, i, |
618 | sig_idx, sortree, &buf_canon, reason); | |
622 | sig_idx, sortree, &buf_canon, reason, section, qstate); | |
619 | 623 | if(sec == sec_status_secure) |
620 | 624 | return sec; |
621 | 625 | } |
1120 | 1124 | * signer name length. |
1121 | 1125 | * @param sortree: if NULL is passed a new sorted rrset tree is built. |
1122 | 1126 | * Otherwise it is reused. |
1127 | * @param section: section of packet where this rrset comes from. | |
1128 | * @param qstate: qstate with region. | |
1123 | 1129 | * @return false on alloc error. |
1124 | 1130 | */ |
1125 | 1131 | static int |
1126 | 1132 | rrset_canonical(struct regional* region, sldns_buffer* buf, |
1127 | 1133 | struct ub_packed_rrset_key* k, uint8_t* sig, size_t siglen, |
1128 | struct rbtree_type** sortree) | |
1134 | struct rbtree_type** sortree, sldns_pkt_section section, | |
1135 | struct module_qstate* qstate) | |
1129 | 1136 | { |
1130 | 1137 | struct packed_rrset_data* d = (struct packed_rrset_data*)k->entry.data; |
1131 | 1138 | uint8_t* can_owner = NULL; |
1174 | 1181 | canonicalize_rdata(buf, k, d->rr_len[walk->rr_idx]); |
1175 | 1182 | } |
1176 | 1183 | sldns_buffer_flip(buf); |
1184 | ||
1185 | /* Replace RR owner with canonical owner for NSEC records in authority | |
1186 | * section, to prevent that a wildcard synthesized NSEC can be used in | |
1187 | * the non-existence proves. */ | |
1188 | if(ntohs(k->rk.type) == LDNS_RR_TYPE_NSEC && | |
1189 | section == LDNS_SECTION_AUTHORITY) { | |
1190 | k->rk.dname = regional_alloc_init(qstate->region, can_owner, | |
1191 | can_owner_len); | |
1192 | if(!k->rk.dname) | |
1193 | return 0; | |
1194 | k->rk.dname_len = can_owner_len; | |
1195 | } | |
1196 | ||
1197 | ||
1177 | 1198 | return 1; |
1178 | 1199 | } |
1179 | 1200 | |
1317 | 1338 | struct val_env* ve, time_t now, |
1318 | 1339 | struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey, |
1319 | 1340 | size_t dnskey_idx, size_t sig_idx, |
1320 | struct rbtree_type** sortree, int* buf_canon, char** reason) | |
1341 | struct rbtree_type** sortree, int* buf_canon, char** reason, | |
1342 | sldns_pkt_section section, struct module_qstate* qstate) | |
1321 | 1343 | { |
1322 | 1344 | enum sec_status sec; |
1323 | 1345 | uint8_t* sig; /* RRSIG rdata */ |
1416 | 1438 | /* create rrset canonical format in buffer, ready for |
1417 | 1439 | * signature */ |
1418 | 1440 | if(!rrset_canonical(region, buf, rrset, sig+2, |
1419 | 18 + signer_len, sortree)) { | |
1441 | 18 + signer_len, sortree, section, qstate)) { | |
1420 | 1442 | log_err("verify: failed due to alloc error"); |
1421 | 1443 | return sec_status_unchecked; |
1422 | 1444 | } |
43 | 43 | #ifndef VALIDATOR_VAL_SIGCRYPT_H |
44 | 44 | #define VALIDATOR_VAL_SIGCRYPT_H |
45 | 45 | #include "util/data/packed_rrset.h" |
46 | #include "sldns/pkthdr.h" | |
46 | 47 | struct val_env; |
47 | 48 | struct module_env; |
49 | struct module_qstate; | |
48 | 50 | struct ub_packed_rrset_key; |
49 | 51 | struct rbtree_type; |
50 | 52 | struct regional; |
236 | 238 | * @param sigalg: if nonNULL provide downgrade protection otherwise one |
237 | 239 | * algorithm is enough. |
238 | 240 | * @param reason: if bogus, a string returned, fixed or alloced in scratch. |
241 | * @param section: section of packet where this rrset comes from. | |
242 | * @param qstate: qstate with region. | |
239 | 243 | * @return SECURE if one key in the set verifies one rrsig. |
240 | 244 | * UNCHECKED on allocation errors, unsupported algorithms, malformed data, |
241 | 245 | * and BOGUS on verification failures (no keys match any signatures). |
242 | 246 | */ |
243 | 247 | enum sec_status dnskeyset_verify_rrset(struct module_env* env, |
244 | 248 | struct val_env* ve, struct ub_packed_rrset_key* rrset, |
245 | struct ub_packed_rrset_key* dnskey, uint8_t* sigalg, char** reason); | |
249 | struct ub_packed_rrset_key* dnskey, uint8_t* sigalg, char** reason, | |
250 | sldns_pkt_section section, struct module_qstate* qstate); | |
246 | 251 | |
247 | 252 | /** |
248 | 253 | * verify rrset against one specific dnskey (from rrset) |
252 | 257 | * @param dnskey: DNSKEY rrset, keyset. |
253 | 258 | * @param dnskey_idx: which key from the rrset to try. |
254 | 259 | * @param reason: if bogus, a string returned, fixed or alloced in scratch. |
260 | * @param section: section of packet where this rrset comes from. | |
261 | * @param qstate: qstate with region. | |
255 | 262 | * @return secure if *this* key signs any of the signatures on rrset. |
256 | 263 | * unchecked on error or and bogus on bad signature. |
257 | 264 | */ |
258 | 265 | enum sec_status dnskey_verify_rrset(struct module_env* env, |
259 | 266 | struct val_env* ve, struct ub_packed_rrset_key* rrset, |
260 | struct ub_packed_rrset_key* dnskey, size_t dnskey_idx, char** reason); | |
267 | struct ub_packed_rrset_key* dnskey, size_t dnskey_idx, char** reason, | |
268 | sldns_pkt_section section, struct module_qstate* qstate); | |
261 | 269 | |
262 | 270 | /** |
263 | 271 | * verify rrset, with dnskey rrset, for a specific rrsig in rrset |
270 | 278 | * @param sortree: reused sorted order. Stored in region. Pass NULL at start, |
271 | 279 | * and for a new rrset. |
272 | 280 | * @param reason: if bogus, a string returned, fixed or alloced in scratch. |
281 | * @param section: section of packet where this rrset comes from. | |
282 | * @param qstate: qstate with region. | |
273 | 283 | * @return secure if any key signs *this* signature. bogus if no key signs it, |
274 | 284 | * or unchecked on error. |
275 | 285 | */ |
276 | 286 | enum sec_status dnskeyset_verify_rrset_sig(struct module_env* env, |
277 | 287 | struct val_env* ve, time_t now, struct ub_packed_rrset_key* rrset, |
278 | 288 | struct ub_packed_rrset_key* dnskey, size_t sig_idx, |
279 | struct rbtree_type** sortree, char** reason); | |
289 | struct rbtree_type** sortree, char** reason, sldns_pkt_section section, | |
290 | struct module_qstate* qstate); | |
280 | 291 | |
281 | 292 | /** |
282 | 293 | * verify rrset, with specific dnskey(from set), for a specific rrsig |
294 | 305 | * pass false at start. pass old value only for same rrset and same |
295 | 306 | * signature (but perhaps different key) for reuse. |
296 | 307 | * @param reason: if bogus, a string returned, fixed or alloced in scratch. |
308 | * @param section: section of packet where this rrset comes from. | |
309 | * @param qstate: qstate with region. | |
297 | 310 | * @return secure if this key signs this signature. unchecked on error or |
298 | 311 | * bogus if it did not validate. |
299 | 312 | */ |
301 | 314 | struct sldns_buffer* buf, struct val_env* ve, time_t now, |
302 | 315 | struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey, |
303 | 316 | size_t dnskey_idx, size_t sig_idx, |
304 | struct rbtree_type** sortree, int* buf_canon, char** reason); | |
317 | struct rbtree_type** sortree, int* buf_canon, char** reason, | |
318 | sldns_pkt_section section, struct module_qstate* qstate); | |
305 | 319 | |
306 | 320 | /** |
307 | 321 | * canonical compare for two tree entries |
334 | 334 | enum sec_status |
335 | 335 | val_verify_rrset(struct module_env* env, struct val_env* ve, |
336 | 336 | struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* keys, |
337 | uint8_t* sigalg, char** reason) | |
337 | uint8_t* sigalg, char** reason, sldns_pkt_section section, | |
338 | struct module_qstate* qstate) | |
338 | 339 | { |
339 | 340 | enum sec_status sec; |
340 | 341 | struct packed_rrset_data* d = (struct packed_rrset_data*)rrset-> |
356 | 357 | } |
357 | 358 | log_nametypeclass(VERB_ALGO, "verify rrset", rrset->rk.dname, |
358 | 359 | ntohs(rrset->rk.type), ntohs(rrset->rk.rrset_class)); |
359 | sec = dnskeyset_verify_rrset(env, ve, rrset, keys, sigalg, reason); | |
360 | sec = dnskeyset_verify_rrset(env, ve, rrset, keys, sigalg, reason, | |
361 | section, qstate); | |
360 | 362 | verbose(VERB_ALGO, "verify result: %s", sec_status_to_string(sec)); |
361 | 363 | regional_free_all(env->scratch); |
362 | 364 | |
389 | 391 | enum sec_status |
390 | 392 | val_verify_rrset_entry(struct module_env* env, struct val_env* ve, |
391 | 393 | struct ub_packed_rrset_key* rrset, struct key_entry_key* kkey, |
392 | char** reason) | |
394 | char** reason, sldns_pkt_section section, struct module_qstate* qstate) | |
393 | 395 | { |
394 | 396 | /* temporary dnskey rrset-key */ |
395 | 397 | struct ub_packed_rrset_key dnskey; |
402 | 404 | dnskey.rk.dname_len = kkey->namelen; |
403 | 405 | dnskey.entry.key = &dnskey; |
404 | 406 | dnskey.entry.data = kd->rrset_data; |
405 | sec = val_verify_rrset(env, ve, rrset, &dnskey, kd->algo, reason); | |
407 | sec = val_verify_rrset(env, ve, rrset, &dnskey, kd->algo, reason, | |
408 | section, qstate); | |
406 | 409 | return sec; |
407 | 410 | } |
408 | 411 | |
410 | 413 | static enum sec_status |
411 | 414 | verify_dnskeys_with_ds_rr(struct module_env* env, struct val_env* ve, |
412 | 415 | struct ub_packed_rrset_key* dnskey_rrset, |
413 | struct ub_packed_rrset_key* ds_rrset, size_t ds_idx, char** reason) | |
416 | struct ub_packed_rrset_key* ds_rrset, size_t ds_idx, char** reason, | |
417 | struct module_qstate* qstate) | |
414 | 418 | { |
415 | 419 | enum sec_status sec = sec_status_bogus; |
416 | 420 | size_t i, num, numchecked = 0, numhashok = 0; |
441 | 445 | /* Otherwise, we have a match! Make sure that the DNSKEY |
442 | 446 | * verifies *with this key* */ |
443 | 447 | sec = dnskey_verify_rrset(env, ve, dnskey_rrset, |
444 | dnskey_rrset, i, reason); | |
448 | dnskey_rrset, i, reason, LDNS_SECTION_ANSWER, qstate); | |
445 | 449 | if(sec == sec_status_secure) { |
446 | 450 | return sec; |
447 | 451 | } |
477 | 481 | enum sec_status |
478 | 482 | val_verify_DNSKEY_with_DS(struct module_env* env, struct val_env* ve, |
479 | 483 | struct ub_packed_rrset_key* dnskey_rrset, |
480 | struct ub_packed_rrset_key* ds_rrset, uint8_t* sigalg, char** reason) | |
484 | struct ub_packed_rrset_key* ds_rrset, uint8_t* sigalg, char** reason, | |
485 | struct module_qstate* qstate) | |
481 | 486 | { |
482 | 487 | /* as long as this is false, we can consider this DS rrset to be |
483 | 488 | * equivalent to no DS rrset. */ |
519 | 524 | has_useful_ds = 1; |
520 | 525 | |
521 | 526 | sec = verify_dnskeys_with_ds_rr(env, ve, dnskey_rrset, |
522 | ds_rrset, i, reason); | |
527 | ds_rrset, i, reason, qstate); | |
523 | 528 | if(sec == sec_status_secure) { |
524 | 529 | if(!sigalg || algo_needs_set_secure(&needs, |
525 | 530 | (uint8_t)ds_get_key_algo(ds_rrset, i))) { |
552 | 557 | struct key_entry_key* |
553 | 558 | val_verify_new_DNSKEYs(struct regional* region, struct module_env* env, |
554 | 559 | struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset, |
555 | struct ub_packed_rrset_key* ds_rrset, int downprot, char** reason) | |
560 | struct ub_packed_rrset_key* ds_rrset, int downprot, char** reason, | |
561 | struct module_qstate* qstate) | |
556 | 562 | { |
557 | 563 | uint8_t sigalg[ALGO_NEEDS_MAX+1]; |
558 | 564 | enum sec_status sec = val_verify_DNSKEY_with_DS(env, ve, |
559 | dnskey_rrset, ds_rrset, downprot?sigalg:NULL, reason); | |
565 | dnskey_rrset, ds_rrset, downprot?sigalg:NULL, reason, qstate); | |
560 | 566 | |
561 | 567 | if(sec == sec_status_secure) { |
562 | 568 | return key_entry_create_rrset(region, |
578 | 584 | val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve, |
579 | 585 | struct ub_packed_rrset_key* dnskey_rrset, |
580 | 586 | struct ub_packed_rrset_key* ta_ds, |
581 | struct ub_packed_rrset_key* ta_dnskey, uint8_t* sigalg, char** reason) | |
587 | struct ub_packed_rrset_key* ta_dnskey, uint8_t* sigalg, char** reason, | |
588 | struct module_qstate* qstate) | |
582 | 589 | { |
583 | 590 | /* as long as this is false, we can consider this anchor to be |
584 | 591 | * equivalent to no anchor. */ |
629 | 636 | has_useful_ta = 1; |
630 | 637 | |
631 | 638 | sec = verify_dnskeys_with_ds_rr(env, ve, dnskey_rrset, |
632 | ta_ds, i, reason); | |
639 | ta_ds, i, reason, qstate); | |
633 | 640 | if(sec == sec_status_secure) { |
634 | 641 | if(!sigalg || algo_needs_set_secure(&needs, |
635 | 642 | (uint8_t)ds_get_key_algo(ta_ds, i))) { |
655 | 662 | has_useful_ta = 1; |
656 | 663 | |
657 | 664 | sec = dnskey_verify_rrset(env, ve, dnskey_rrset, |
658 | ta_dnskey, i, reason); | |
665 | ta_dnskey, i, reason, LDNS_SECTION_ANSWER, qstate); | |
659 | 666 | if(sec == sec_status_secure) { |
660 | 667 | if(!sigalg || algo_needs_set_secure(&needs, |
661 | 668 | (uint8_t)dnskey_get_algo(ta_dnskey, i))) { |
689 | 696 | struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset, |
690 | 697 | struct ub_packed_rrset_key* ta_ds_rrset, |
691 | 698 | struct ub_packed_rrset_key* ta_dnskey_rrset, int downprot, |
692 | char** reason) | |
699 | char** reason, struct module_qstate* qstate) | |
693 | 700 | { |
694 | 701 | uint8_t sigalg[ALGO_NEEDS_MAX+1]; |
695 | 702 | enum sec_status sec = val_verify_DNSKEY_with_TA(env, ve, |
696 | 703 | dnskey_rrset, ta_ds_rrset, ta_dnskey_rrset, |
697 | downprot?sigalg:NULL, reason); | |
704 | downprot?sigalg:NULL, reason, qstate); | |
698 | 705 | |
699 | 706 | if(sec == sec_status_secure) { |
700 | 707 | return key_entry_create_rrset(region, |
41 | 41 | #ifndef VALIDATOR_VAL_UTILS_H |
42 | 42 | #define VALIDATOR_VAL_UTILS_H |
43 | 43 | #include "util/data/packed_rrset.h" |
44 | #include "sldns/pkthdr.h" | |
44 | 45 | struct query_info; |
45 | 46 | struct reply_info; |
46 | 47 | struct val_env; |
47 | 48 | struct module_env; |
49 | struct module_qstate; | |
48 | 50 | struct ub_packed_rrset_key; |
49 | 51 | struct key_entry_key; |
50 | 52 | struct regional; |
119 | 121 | * @param sigalg: if nonNULL provide downgrade protection otherwise one |
120 | 122 | * algorithm is enough. Algo list is constructed in here. |
121 | 123 | * @param reason: reason of failure. Fixed string or alloced in scratch. |
124 | * @param section: section of packet where this rrset comes from. | |
125 | * @param qstate: qstate with region. | |
122 | 126 | * @return security status of verification. |
123 | 127 | */ |
124 | 128 | enum sec_status val_verify_rrset(struct module_env* env, struct val_env* ve, |
125 | 129 | struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* keys, |
126 | uint8_t* sigalg, char** reason); | |
130 | uint8_t* sigalg, char** reason, sldns_pkt_section section, | |
131 | struct module_qstate* qstate); | |
127 | 132 | |
128 | 133 | /** |
129 | 134 | * Verify RRset with keys from a keyset. |
132 | 137 | * @param rrset: what to verify |
133 | 138 | * @param kkey: key_entry to verify with. |
134 | 139 | * @param reason: reason of failure. Fixed string or alloced in scratch. |
140 | * @param section: section of packet where this rrset comes from. | |
141 | * @param qstate: qstate with region. | |
135 | 142 | * @return security status of verification. |
136 | 143 | */ |
137 | 144 | enum sec_status val_verify_rrset_entry(struct module_env* env, |
138 | 145 | struct val_env* ve, struct ub_packed_rrset_key* rrset, |
139 | struct key_entry_key* kkey, char** reason); | |
146 | struct key_entry_key* kkey, char** reason, sldns_pkt_section section, | |
147 | struct module_qstate* qstate); | |
140 | 148 | |
141 | 149 | /** |
142 | 150 | * Verify DNSKEYs with DS rrset. Like val_verify_new_DNSKEYs but |
149 | 157 | * algorithm is enough. The list of signalled algorithms is returned, |
150 | 158 | * must have enough space for ALGO_NEEDS_MAX+1. |
151 | 159 | * @param reason: reason of failure. Fixed string or alloced in scratch. |
160 | * @param qstate: qstate with region. | |
152 | 161 | * @return: sec_status_secure if a DS matches. |
153 | 162 | * sec_status_insecure if end of trust (i.e., unknown algorithms). |
154 | 163 | * sec_status_bogus if it fails. |
155 | 164 | */ |
156 | 165 | enum sec_status val_verify_DNSKEY_with_DS(struct module_env* env, |
157 | 166 | struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset, |
158 | struct ub_packed_rrset_key* ds_rrset, uint8_t* sigalg, char** reason); | |
167 | struct ub_packed_rrset_key* ds_rrset, uint8_t* sigalg, char** reason, | |
168 | struct module_qstate* qstate); | |
159 | 169 | |
160 | 170 | /** |
161 | 171 | * Verify DNSKEYs with DS and DNSKEY rrset. Like val_verify_DNSKEY_with_DS |
169 | 179 | * algorithm is enough. The list of signalled algorithms is returned, |
170 | 180 | * must have enough space for ALGO_NEEDS_MAX+1. |
171 | 181 | * @param reason: reason of failure. Fixed string or alloced in scratch. |
182 | * @param qstate: qstate with region. | |
172 | 183 | * @return: sec_status_secure if a DS matches. |
173 | 184 | * sec_status_insecure if end of trust (i.e., unknown algorithms). |
174 | 185 | * sec_status_bogus if it fails. |
176 | 187 | enum sec_status val_verify_DNSKEY_with_TA(struct module_env* env, |
177 | 188 | struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset, |
178 | 189 | struct ub_packed_rrset_key* ta_ds, |
179 | struct ub_packed_rrset_key* ta_dnskey, uint8_t* sigalg, char** reason); | |
190 | struct ub_packed_rrset_key* ta_dnskey, uint8_t* sigalg, char** reason, | |
191 | struct module_qstate* qstate); | |
180 | 192 | |
181 | 193 | /** |
182 | 194 | * Verify new DNSKEYs with DS rrset. The DS contains hash values that should |
191 | 203 | * @param downprot: if true provide downgrade protection otherwise one |
192 | 204 | * algorithm is enough. |
193 | 205 | * @param reason: reason of failure. Fixed string or alloced in scratch. |
206 | * @param qstate: qstate with region. | |
194 | 207 | * @return a KeyEntry. This will either contain the now trusted |
195 | 208 | * dnskey_rrset, a "null" key entry indicating that this DS |
196 | 209 | * rrset/DNSKEY pair indicate an secure end to the island of trust |
204 | 217 | struct key_entry_key* val_verify_new_DNSKEYs(struct regional* region, |
205 | 218 | struct module_env* env, struct val_env* ve, |
206 | 219 | struct ub_packed_rrset_key* dnskey_rrset, |
207 | struct ub_packed_rrset_key* ds_rrset, int downprot, char** reason); | |
220 | struct ub_packed_rrset_key* ds_rrset, int downprot, char** reason, | |
221 | struct module_qstate* qstate); | |
208 | 222 | |
209 | 223 | |
210 | 224 | /** |
219 | 233 | * @param downprot: if true provide downgrade protection otherwise one |
220 | 234 | * algorithm is enough. |
221 | 235 | * @param reason: reason of failure. Fixed string or alloced in scratch. |
236 | * @param qstate: qstate with region. | |
222 | 237 | * @return a KeyEntry. This will either contain the now trusted |
223 | 238 | * dnskey_rrset, a "null" key entry indicating that this DS |
224 | 239 | * rrset/DNSKEY pair indicate an secure end to the island of trust |
234 | 249 | struct ub_packed_rrset_key* dnskey_rrset, |
235 | 250 | struct ub_packed_rrset_key* ta_ds_rrset, |
236 | 251 | struct ub_packed_rrset_key* ta_dnskey_rrset, |
237 | int downprot, char** reason); | |
252 | int downprot, char** reason, struct module_qstate* qstate); | |
238 | 253 | |
239 | 254 | /** |
240 | 255 | * Determine if DS rrset is usable for validator or not. |
251 | 266 | * the result of a wildcard expansion. If so, return the name of the |
252 | 267 | * generating wildcard. |
253 | 268 | * |
254 | * @param rrset The rrset to chedck. | |
269 | * @param rrset The rrset to check. | |
255 | 270 | * @param wc: the wildcard name, if the rrset was synthesized from a wildcard. |
256 | 271 | * unchanged if not. The wildcard name, without "*." in front, is |
257 | 272 | * returned. This is a pointer into the rrset owner name. |
571 | 571 | } |
572 | 572 | |
573 | 573 | /* Verify the answer rrset */ |
574 | sec = val_verify_rrset_entry(env, ve, s, key_entry, &reason); | |
574 | sec = val_verify_rrset_entry(env, ve, s, key_entry, &reason, | |
575 | LDNS_SECTION_ANSWER, qstate); | |
575 | 576 | /* If the (answer) rrset failed to validate, then this |
576 | 577 | * message is BAD. */ |
577 | 578 | if(sec != sec_status_secure) { |
600 | 601 | for(i=chase_reply->an_numrrsets; i<chase_reply->an_numrrsets+ |
601 | 602 | chase_reply->ns_numrrsets; i++) { |
602 | 603 | s = chase_reply->rrsets[i]; |
603 | sec = val_verify_rrset_entry(env, ve, s, key_entry, &reason); | |
604 | sec = val_verify_rrset_entry(env, ve, s, key_entry, &reason, | |
605 | LDNS_SECTION_AUTHORITY, qstate); | |
604 | 606 | /* If anything in the authority section fails to be secure, |
605 | 607 | * we have a bad message. */ |
606 | 608 | if(sec != sec_status_secure) { |
628 | 630 | val_find_rrset_signer(s, &sname, &slen); |
629 | 631 | if(sname && query_dname_compare(sname, key_entry->name)==0) |
630 | 632 | (void)val_verify_rrset_entry(env, ve, s, key_entry, |
631 | &reason); | |
633 | &reason, LDNS_SECTION_ADDITIONAL, qstate); | |
632 | 634 | /* the additional section can fail to be secure, |
633 | 635 | * it is optional, check signature in case we need |
634 | 636 | * to clean the additional section later. */ |
2483 | 2485 | /* attempt to verify with trust anchor DS and DNSKEY */ |
2484 | 2486 | kkey = val_verify_new_DNSKEYs_with_ta(qstate->region, qstate->env, ve, |
2485 | 2487 | dnskey_rrset, ta->ds_rrset, ta->dnskey_rrset, downprot, |
2486 | &reason); | |
2488 | &reason, qstate); | |
2487 | 2489 | if(!kkey) { |
2488 | 2490 | log_err("out of memory: verifying prime TA"); |
2489 | 2491 | return NULL; |
2573 | 2575 | /* Verify only returns BOGUS or SECURE. If the rrset is |
2574 | 2576 | * bogus, then we are done. */ |
2575 | 2577 | sec = val_verify_rrset_entry(qstate->env, ve, ds, |
2576 | vq->key_entry, &reason); | |
2578 | vq->key_entry, &reason, LDNS_SECTION_ANSWER, qstate); | |
2577 | 2579 | if(sec != sec_status_secure) { |
2578 | 2580 | verbose(VERB_DETAIL, "DS rrset in DS response did " |
2579 | 2581 | "not verify"); |
2620 | 2622 | /* Try to prove absence of the DS with NSEC */ |
2621 | 2623 | sec = val_nsec_prove_nodata_dsreply( |
2622 | 2624 | qstate->env, ve, qinfo, msg->rep, vq->key_entry, |
2623 | &proof_ttl, &reason); | |
2625 | &proof_ttl, &reason, qstate); | |
2624 | 2626 | switch(sec) { |
2625 | 2627 | case sec_status_secure: |
2626 | 2628 | verbose(VERB_DETAIL, "NSEC RRset for the " |
2648 | 2650 | |
2649 | 2651 | sec = nsec3_prove_nods(qstate->env, ve, |
2650 | 2652 | msg->rep->rrsets + msg->rep->an_numrrsets, |
2651 | msg->rep->ns_numrrsets, qinfo, vq->key_entry, &reason); | |
2653 | msg->rep->ns_numrrsets, qinfo, vq->key_entry, &reason, | |
2654 | qstate); | |
2652 | 2655 | switch(sec) { |
2653 | 2656 | case sec_status_insecure: |
2654 | 2657 | /* case insecure also continues to unsigned |
2709 | 2712 | goto return_bogus; |
2710 | 2713 | } |
2711 | 2714 | sec = val_verify_rrset_entry(qstate->env, ve, cname, |
2712 | vq->key_entry, &reason); | |
2715 | vq->key_entry, &reason, LDNS_SECTION_ANSWER, qstate); | |
2713 | 2716 | if(sec == sec_status_secure) { |
2714 | 2717 | verbose(VERB_ALGO, "CNAME validated, " |
2715 | 2718 | "proof that DS does not exist"); |
2875 | 2878 | } |
2876 | 2879 | downprot = qstate->env->cfg->harden_algo_downgrade; |
2877 | 2880 | vq->key_entry = val_verify_new_DNSKEYs(qstate->region, qstate->env, |
2878 | ve, dnskey, vq->ds_rrset, downprot, &reason); | |
2881 | ve, dnskey, vq->ds_rrset, downprot, &reason, qstate); | |
2879 | 2882 | |
2880 | 2883 | if(!vq->key_entry) { |
2881 | 2884 | log_err("out of memory in verify new DNSKEYs"); |
2951 | 2954 | } |
2952 | 2955 | |
2953 | 2956 | if(ta->autr) { |
2954 | if(!autr_process_prime(qstate->env, ve, ta, dnskey_rrset)) { | |
2957 | if(!autr_process_prime(qstate->env, ve, ta, dnskey_rrset, | |
2958 | qstate)) { | |
2955 | 2959 | /* trust anchor revoked, restart with less anchors */ |
2956 | 2960 | vq->state = VAL_INIT_STATE; |
2957 | 2961 | vq->trust_anchor_name = NULL; |