00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <config.h>
00019
00020 #include <isc/base32.h>
00021 #include <isc/mem.h>
00022 #include <isc/print.h>
00023 #include <isc/sha2.h>
00024 #include <isc/string.h>
00025 #include <isc/task.h>
00026 #include <isc/util.h>
00027
00028 #include <dns/db.h>
00029 #include <dns/dnssec.h>
00030 #include <dns/ds.h>
00031 #include <dns/events.h>
00032 #include <dns/keytable.h>
00033 #include <dns/keyvalues.h>
00034 #include <dns/log.h>
00035 #include <dns/message.h>
00036 #include <dns/ncache.h>
00037 #include <dns/nsec.h>
00038 #include <dns/nsec3.h>
00039 #include <dns/rdata.h>
00040 #include <dns/rdataset.h>
00041 #include <dns/rdatatype.h>
00042 #include <dns/resolver.h>
00043 #include <dns/result.h>
00044 #include <dns/validator.h>
00045 #include <dns/view.h>
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 #define VALIDATOR_MAGIC ISC_MAGIC('V', 'a', 'l', '?')
00087 #define VALID_VALIDATOR(v) ISC_MAGIC_VALID(v, VALIDATOR_MAGIC)
00088
00089 #define VALATTR_SHUTDOWN 0x0001
00090 #define VALATTR_CANCELED 0x0002
00091 #define VALATTR_TRIEDVERIFY 0x0004
00092
00093 #define VALATTR_INSECURITY 0x0010
00094 #define VALATTR_DLVTRIED 0x0020
00095
00096
00097
00098
00099 #define VALATTR_NEEDNOQNAME 0x00000100
00100 #define VALATTR_NEEDNOWILDCARD 0x00000200
00101 #define VALATTR_NEEDNODATA 0x00000400
00102
00103
00104
00105
00106 #define VALATTR_FOUNDNOQNAME 0x00001000
00107 #define VALATTR_FOUNDNOWILDCARD 0x00002000
00108 #define VALATTR_FOUNDNODATA 0x00004000
00109 #define VALATTR_FOUNDCLOSEST 0x00008000
00110
00111
00112
00113
00114 #define VALATTR_FOUNDOPTOUT 0x00010000
00115 #define VALATTR_FOUNDUNKNOWN 0x00020000
00116
00117 #define NEEDNODATA(val) ((val->attributes & VALATTR_NEEDNODATA) != 0)
00118 #define NEEDNOQNAME(val) ((val->attributes & VALATTR_NEEDNOQNAME) != 0)
00119 #define NEEDNOWILDCARD(val) ((val->attributes & VALATTR_NEEDNOWILDCARD) != 0)
00120 #define DLVTRIED(val) ((val->attributes & VALATTR_DLVTRIED) != 0)
00121 #define FOUNDNODATA(val) ((val->attributes & VALATTR_FOUNDNODATA) != 0)
00122 #define FOUNDNOQNAME(val) ((val->attributes & VALATTR_FOUNDNOQNAME) != 0)
00123 #define FOUNDNOWILDCARD(val) ((val->attributes & VALATTR_FOUNDNOWILDCARD) != 0)
00124 #define FOUNDCLOSEST(val) ((val->attributes & VALATTR_FOUNDCLOSEST) != 0)
00125 #define FOUNDOPTOUT(val) ((val->attributes & VALATTR_FOUNDOPTOUT) != 0)
00126
00127 #define SHUTDOWN(v) (((v)->attributes & VALATTR_SHUTDOWN) != 0)
00128 #define CANCELED(v) (((v)->attributes & VALATTR_CANCELED) != 0)
00129
00130 #define NEGATIVE(r) (((r)->attributes & DNS_RDATASETATTR_NEGATIVE) != 0)
00131
00132 static void
00133 destroy(dns_validator_t *val);
00134
00135 static isc_result_t
00136 get_dst_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo,
00137 dns_rdataset_t *rdataset);
00138
00139 static isc_result_t
00140 validate(dns_validator_t *val, isc_boolean_t resume);
00141
00142 static isc_result_t
00143 validatezonekey(dns_validator_t *val);
00144
00145 static isc_result_t
00146 nsecvalidate(dns_validator_t *val, isc_boolean_t resume);
00147
00148 static isc_result_t
00149 proveunsecure(dns_validator_t *val, isc_boolean_t have_ds,
00150 isc_boolean_t resume);
00151
00152 static void
00153 validator_logv(dns_validator_t *val, isc_logcategory_t *category,
00154 isc_logmodule_t *module, int level, const char *fmt, va_list ap)
00155 ISC_FORMAT_PRINTF(5, 0);
00156
00157 static void
00158 validator_log(void *val, int level, const char *fmt, ...)
00159 ISC_FORMAT_PRINTF(3, 4);
00160
00161 static void
00162 validator_logcreate(dns_validator_t *val,
00163 dns_name_t *name, dns_rdatatype_t type,
00164 const char *caller, const char *operation);
00165
00166 static isc_result_t
00167 dlv_validatezonekey(dns_validator_t *val);
00168
00169 static void
00170 dlv_validator_start(dns_validator_t *val);
00171
00172 static isc_result_t
00173 finddlvsep(dns_validator_t *val, isc_boolean_t resume);
00174
00175 static isc_result_t
00176 startfinddlvsep(dns_validator_t *val, dns_name_t *unsecure);
00177
00178
00179
00180
00181 static inline void
00182 markanswer(dns_validator_t *val, const char *where) {
00183 validator_log(val, ISC_LOG_DEBUG(3), "marking as answer (%s)", where);
00184 if (val->event->rdataset != NULL)
00185 dns_rdataset_settrust(val->event->rdataset, dns_trust_answer);
00186 if (val->event->sigrdataset != NULL)
00187 dns_rdataset_settrust(val->event->sigrdataset,
00188 dns_trust_answer);
00189 }
00190
00191 static inline void
00192 marksecure(dns_validatorevent_t *event) {
00193 dns_rdataset_settrust(event->rdataset, dns_trust_secure);
00194 if (event->sigrdataset != NULL)
00195 dns_rdataset_settrust(event->sigrdataset, dns_trust_secure);
00196 event->secure = ISC_TRUE;
00197 }
00198
00199 static void
00200 validator_done(dns_validator_t *val, isc_result_t result) {
00201 isc_task_t *task;
00202
00203 if (val->event == NULL)
00204 return;
00205
00206
00207
00208
00209
00210 val->event->result = result;
00211 task = val->event->ev_sender;
00212 val->event->ev_sender = val;
00213 val->event->ev_type = DNS_EVENT_VALIDATORDONE;
00214 val->event->ev_action = val->action;
00215 val->event->ev_arg = val->arg;
00216 isc_task_sendanddetach(&task, (isc_event_t **)&val->event);
00217 }
00218
00219 static inline isc_boolean_t
00220 exit_check(dns_validator_t *val) {
00221
00222
00223
00224 if (!SHUTDOWN(val))
00225 return (ISC_FALSE);
00226
00227 INSIST(val->event == NULL);
00228
00229 if (val->fetch != NULL || val->subvalidator != NULL)
00230 return (ISC_FALSE);
00231
00232 return (ISC_TRUE);
00233 }
00234
00235
00236
00237
00238 static inline isc_boolean_t
00239 dlv_algorithm_supported(dns_validator_t *val) {
00240 dns_rdata_t rdata = DNS_RDATA_INIT;
00241 dns_rdata_dlv_t dlv;
00242 isc_result_t result;
00243
00244 for (result = dns_rdataset_first(&val->dlv);
00245 result == ISC_R_SUCCESS;
00246 result = dns_rdataset_next(&val->dlv)) {
00247 dns_rdata_reset(&rdata);
00248 dns_rdataset_current(&val->dlv, &rdata);
00249 result = dns_rdata_tostruct(&rdata, &dlv, NULL);
00250 RUNTIME_CHECK(result == ISC_R_SUCCESS);
00251
00252 if (!dns_resolver_algorithm_supported(val->view->resolver,
00253 val->event->name,
00254 dlv.algorithm))
00255 continue;
00256
00257 if (!dns_resolver_ds_digest_supported(val->view->resolver,
00258 val->event->name,
00259 dlv.digest_type))
00260 continue;
00261
00262 return (ISC_TRUE);
00263 }
00264 return (ISC_FALSE);
00265 }
00266
00267
00268
00269
00270
00271 static isc_boolean_t
00272 isdelegation(dns_name_t *name, dns_rdataset_t *rdataset,
00273 isc_result_t dbresult)
00274 {
00275 dns_fixedname_t fixed;
00276 dns_label_t hashlabel;
00277 dns_name_t nsec3name;
00278 dns_rdata_nsec3_t nsec3;
00279 dns_rdata_t rdata = DNS_RDATA_INIT;
00280 dns_rdataset_t set;
00281 int order;
00282 int scope;
00283 isc_boolean_t found;
00284 isc_buffer_t buffer;
00285 isc_result_t result;
00286 unsigned char hash[NSEC3_MAX_HASH_LENGTH];
00287 unsigned char owner[NSEC3_MAX_HASH_LENGTH];
00288 unsigned int length;
00289
00290 REQUIRE(dbresult == DNS_R_NXRRSET || dbresult == DNS_R_NCACHENXRRSET);
00291
00292 dns_rdataset_init(&set);
00293 if (dbresult == DNS_R_NXRRSET)
00294 dns_rdataset_clone(rdataset, &set);
00295 else {
00296 result = dns_ncache_getrdataset(rdataset, name,
00297 dns_rdatatype_nsec, &set);
00298 if (result == ISC_R_NOTFOUND)
00299 goto trynsec3;
00300 if (result != ISC_R_SUCCESS)
00301 return (ISC_FALSE);
00302 }
00303
00304 INSIST(set.type == dns_rdatatype_nsec);
00305
00306 found = ISC_FALSE;
00307 result = dns_rdataset_first(&set);
00308 if (result == ISC_R_SUCCESS) {
00309 dns_rdataset_current(&set, &rdata);
00310 found = dns_nsec_typepresent(&rdata, dns_rdatatype_ns);
00311 dns_rdata_reset(&rdata);
00312 }
00313 dns_rdataset_disassociate(&set);
00314 return (found);
00315
00316 trynsec3:
00317
00318
00319
00320 found = ISC_FALSE;
00321 dns_name_init(&nsec3name, NULL);
00322 dns_fixedname_init(&fixed);
00323 dns_name_downcase(name, dns_fixedname_name(&fixed), NULL);
00324 name = dns_fixedname_name(&fixed);
00325 for (result = dns_rdataset_first(rdataset);
00326 result == ISC_R_SUCCESS;
00327 result = dns_rdataset_next(rdataset))
00328 {
00329 dns_ncache_current(rdataset, &nsec3name, &set);
00330 if (set.type != dns_rdatatype_nsec3) {
00331 dns_rdataset_disassociate(&set);
00332 continue;
00333 }
00334 dns_name_getlabel(&nsec3name, 0, &hashlabel);
00335 isc_region_consume(&hashlabel, 1);
00336 isc_buffer_init(&buffer, owner, sizeof(owner));
00337 result = isc_base32hexnp_decoderegion(&hashlabel, &buffer);
00338 if (result != ISC_R_SUCCESS) {
00339 dns_rdataset_disassociate(&set);
00340 continue;
00341 }
00342 for (result = dns_rdataset_first(&set);
00343 result == ISC_R_SUCCESS;
00344 result = dns_rdataset_next(&set))
00345 {
00346 dns_rdata_reset(&rdata);
00347 dns_rdataset_current(&set, &rdata);
00348 (void)dns_rdata_tostruct(&rdata, &nsec3, NULL);
00349 if (nsec3.hash != 1)
00350 continue;
00351 length = isc_iterated_hash(hash, nsec3.hash,
00352 nsec3.iterations, nsec3.salt,
00353 nsec3.salt_length,
00354 name->ndata, name->length);
00355 if (length != isc_buffer_usedlength(&buffer))
00356 continue;
00357 order = memcmp(hash, owner, length);
00358 if (order == 0) {
00359 found = dns_nsec3_typepresent(&rdata,
00360 dns_rdatatype_ns);
00361 dns_rdataset_disassociate(&set);
00362 return (found);
00363 }
00364 if ((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) == 0)
00365 continue;
00366
00367
00368
00369 scope = memcmp(owner, nsec3.next, nsec3.next_length);
00370 if ((scope < 0 && order > 0 &&
00371 memcmp(hash, nsec3.next, length) < 0) ||
00372 (scope >= 0 && (order > 0 ||
00373 memcmp(hash, nsec3.next, length) < 0)))
00374 {
00375 dns_rdataset_disassociate(&set);
00376 return (ISC_TRUE);
00377 }
00378 }
00379 dns_rdataset_disassociate(&set);
00380 }
00381 return (found);
00382 }
00383
00384
00385
00386
00387
00388
00389 static void
00390 fetch_callback_validator(isc_task_t *task, isc_event_t *event) {
00391 dns_fetchevent_t *devent;
00392 dns_validator_t *val;
00393 dns_rdataset_t *rdataset;
00394 isc_boolean_t want_destroy;
00395 isc_result_t result;
00396 isc_result_t eresult;
00397 isc_result_t saved_result;
00398 dns_fetch_t *fetch;
00399
00400 UNUSED(task);
00401 INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
00402 devent = (dns_fetchevent_t *)event;
00403 val = devent->ev_arg;
00404 rdataset = &val->frdataset;
00405 eresult = devent->result;
00406
00407
00408 if (devent->node != NULL)
00409 dns_db_detachnode(devent->db, &devent->node);
00410 if (devent->db != NULL)
00411 dns_db_detach(&devent->db);
00412 if (dns_rdataset_isassociated(&val->fsigrdataset))
00413 dns_rdataset_disassociate(&val->fsigrdataset);
00414 isc_event_free(&event);
00415
00416 INSIST(val->event != NULL);
00417
00418 validator_log(val, ISC_LOG_DEBUG(3), "in fetch_callback_validator");
00419 LOCK(&val->lock);
00420 fetch = val->fetch;
00421 val->fetch = NULL;
00422 if (CANCELED(val)) {
00423 validator_done(val, ISC_R_CANCELED);
00424 } else if (eresult == ISC_R_SUCCESS) {
00425 validator_log(val, ISC_LOG_DEBUG(3),
00426 "keyset with trust %s",
00427 dns_trust_totext(rdataset->trust));
00428
00429
00430
00431 if (rdataset->trust >= dns_trust_secure) {
00432 result = get_dst_key(val, val->siginfo, rdataset);
00433 if (result == ISC_R_SUCCESS)
00434 val->keyset = &val->frdataset;
00435 }
00436 result = validate(val, ISC_TRUE);
00437 if (result == DNS_R_NOVALIDSIG &&
00438 (val->attributes & VALATTR_TRIEDVERIFY) == 0)
00439 {
00440 saved_result = result;
00441 validator_log(val, ISC_LOG_DEBUG(3),
00442 "falling back to insecurity proof");
00443 val->attributes |= VALATTR_INSECURITY;
00444 result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
00445 if (result == DNS_R_NOTINSECURE)
00446 result = saved_result;
00447 }
00448 if (result != DNS_R_WAIT)
00449 validator_done(val, result);
00450 } else {
00451 validator_log(val, ISC_LOG_DEBUG(3),
00452 "fetch_callback_validator: got %s",
00453 isc_result_totext(eresult));
00454 if (eresult == ISC_R_CANCELED)
00455 validator_done(val, eresult);
00456 else
00457 validator_done(val, DNS_R_BROKENCHAIN);
00458 }
00459 want_destroy = exit_check(val);
00460 UNLOCK(&val->lock);
00461 if (fetch != NULL)
00462 dns_resolver_destroyfetch(&fetch);
00463 if (want_destroy)
00464 destroy(val);
00465 }
00466
00467
00468
00469
00470
00471
00472 static void
00473 dsfetched(isc_task_t *task, isc_event_t *event) {
00474 dns_fetchevent_t *devent;
00475 dns_validator_t *val;
00476 dns_rdataset_t *rdataset;
00477 isc_boolean_t want_destroy;
00478 isc_result_t result;
00479 isc_result_t eresult;
00480 dns_fetch_t *fetch;
00481
00482 UNUSED(task);
00483 INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
00484 devent = (dns_fetchevent_t *)event;
00485 val = devent->ev_arg;
00486 rdataset = &val->frdataset;
00487 eresult = devent->result;
00488
00489
00490 if (devent->node != NULL)
00491 dns_db_detachnode(devent->db, &devent->node);
00492 if (devent->db != NULL)
00493 dns_db_detach(&devent->db);
00494 if (dns_rdataset_isassociated(&val->fsigrdataset))
00495 dns_rdataset_disassociate(&val->fsigrdataset);
00496 isc_event_free(&event);
00497
00498 INSIST(val->event != NULL);
00499
00500 validator_log(val, ISC_LOG_DEBUG(3), "in dsfetched");
00501 LOCK(&val->lock);
00502 fetch = val->fetch;
00503 val->fetch = NULL;
00504 if (CANCELED(val)) {
00505 validator_done(val, ISC_R_CANCELED);
00506 } else if (eresult == ISC_R_SUCCESS) {
00507 validator_log(val, ISC_LOG_DEBUG(3),
00508 "dsset with trust %s",
00509 dns_trust_totext(rdataset->trust));
00510 val->dsset = &val->frdataset;
00511 result = validatezonekey(val);
00512 if (result != DNS_R_WAIT)
00513 validator_done(val, result);
00514 } else if (eresult == DNS_R_CNAME ||
00515 eresult == DNS_R_NXRRSET ||
00516 eresult == DNS_R_NCACHENXRRSET ||
00517 eresult == DNS_R_SERVFAIL)
00518 {
00519 validator_log(val, ISC_LOG_DEBUG(3),
00520 "falling back to insecurity proof (%s)",
00521 dns_result_totext(eresult));
00522 val->attributes |= VALATTR_INSECURITY;
00523 result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
00524 if (result != DNS_R_WAIT)
00525 validator_done(val, result);
00526 } else {
00527 validator_log(val, ISC_LOG_DEBUG(3),
00528 "dsfetched: got %s",
00529 isc_result_totext(eresult));
00530 if (eresult == ISC_R_CANCELED)
00531 validator_done(val, eresult);
00532 else
00533 validator_done(val, DNS_R_BROKENCHAIN);
00534 }
00535 want_destroy = exit_check(val);
00536 UNLOCK(&val->lock);
00537 if (fetch != NULL)
00538 dns_resolver_destroyfetch(&fetch);
00539 if (want_destroy)
00540 destroy(val);
00541 }
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554 static void
00555 dsfetched2(isc_task_t *task, isc_event_t *event) {
00556 dns_fetchevent_t *devent;
00557 dns_validator_t *val;
00558 dns_name_t *tname;
00559 isc_boolean_t want_destroy;
00560 isc_result_t result;
00561 isc_result_t eresult;
00562 dns_fetch_t *fetch;
00563
00564 UNUSED(task);
00565 INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
00566 devent = (dns_fetchevent_t *)event;
00567 val = devent->ev_arg;
00568 eresult = devent->result;
00569
00570
00571 if (devent->node != NULL)
00572 dns_db_detachnode(devent->db, &devent->node);
00573 if (devent->db != NULL)
00574 dns_db_detach(&devent->db);
00575 if (dns_rdataset_isassociated(&val->fsigrdataset))
00576 dns_rdataset_disassociate(&val->fsigrdataset);
00577
00578 INSIST(val->event != NULL);
00579
00580 validator_log(val, ISC_LOG_DEBUG(3), "in dsfetched2: %s",
00581 dns_result_totext(eresult));
00582 LOCK(&val->lock);
00583 fetch = val->fetch;
00584 val->fetch = NULL;
00585 if (CANCELED(val)) {
00586 validator_done(val, ISC_R_CANCELED);
00587 } else if (eresult == DNS_R_CNAME ||
00588 eresult == DNS_R_NXRRSET ||
00589 eresult == DNS_R_NCACHENXRRSET)
00590 {
00591
00592
00593
00594 tname = dns_fixedname_name(&devent->foundname);
00595 if (eresult != DNS_R_CNAME &&
00596 isdelegation(tname, &val->frdataset, eresult)) {
00597 if (val->mustbesecure) {
00598 validator_log(val, ISC_LOG_WARNING,
00599 "must be secure failure, no DS"
00600 " and this is a delegation");
00601 validator_done(val, DNS_R_MUSTBESECURE);
00602 } else if (val->view->dlv == NULL || DLVTRIED(val)) {
00603 markanswer(val, "dsfetched2");
00604 validator_done(val, ISC_R_SUCCESS);
00605 } else {
00606 result = startfinddlvsep(val, tname);
00607 if (result != DNS_R_WAIT)
00608 validator_done(val, result);
00609 }
00610 } else {
00611 result = proveunsecure(val, ISC_FALSE, ISC_TRUE);
00612 if (result != DNS_R_WAIT)
00613 validator_done(val, result);
00614 }
00615 } else if (eresult == ISC_R_SUCCESS ||
00616 eresult == DNS_R_NXDOMAIN ||
00617 eresult == DNS_R_NCACHENXDOMAIN)
00618 {
00619
00620
00621
00622
00623
00624 result = proveunsecure(val, ISC_TF(eresult == ISC_R_SUCCESS),
00625 ISC_TRUE);
00626 if (result != DNS_R_WAIT)
00627 validator_done(val, result);
00628 } else {
00629 if (eresult == ISC_R_CANCELED)
00630 validator_done(val, eresult);
00631 else
00632 validator_done(val, DNS_R_NOVALIDDS);
00633 }
00634 isc_event_free(&event);
00635 want_destroy = exit_check(val);
00636 UNLOCK(&val->lock);
00637 if (fetch != NULL)
00638 dns_resolver_destroyfetch(&fetch);
00639 if (want_destroy)
00640 destroy(val);
00641 }
00642
00643
00644
00645
00646
00647
00648 static void
00649 keyvalidated(isc_task_t *task, isc_event_t *event) {
00650 dns_validatorevent_t *devent;
00651 dns_validator_t *val;
00652 isc_boolean_t want_destroy;
00653 isc_result_t result;
00654 isc_result_t eresult;
00655 isc_result_t saved_result;
00656
00657 UNUSED(task);
00658 INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
00659
00660 devent = (dns_validatorevent_t *)event;
00661 val = devent->ev_arg;
00662 eresult = devent->result;
00663
00664 isc_event_free(&event);
00665 dns_validator_destroy(&val->subvalidator);
00666
00667 INSIST(val->event != NULL);
00668
00669 validator_log(val, ISC_LOG_DEBUG(3), "in keyvalidated");
00670 LOCK(&val->lock);
00671 if (CANCELED(val)) {
00672 validator_done(val, ISC_R_CANCELED);
00673 } else if (eresult == ISC_R_SUCCESS) {
00674 validator_log(val, ISC_LOG_DEBUG(3),
00675 "keyset with trust %s",
00676 dns_trust_totext(val->frdataset.trust));
00677
00678
00679
00680 if (val->frdataset.trust >= dns_trust_secure)
00681 (void) get_dst_key(val, val->siginfo, &val->frdataset);
00682 result = validate(val, ISC_TRUE);
00683 if (result == DNS_R_NOVALIDSIG &&
00684 (val->attributes & VALATTR_TRIEDVERIFY) == 0)
00685 {
00686 saved_result = result;
00687 validator_log(val, ISC_LOG_DEBUG(3),
00688 "falling back to insecurity proof");
00689 val->attributes |= VALATTR_INSECURITY;
00690 result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
00691 if (result == DNS_R_NOTINSECURE)
00692 result = saved_result;
00693 }
00694 if (result != DNS_R_WAIT)
00695 validator_done(val, result);
00696 } else {
00697 if (eresult != DNS_R_BROKENCHAIN) {
00698 if (dns_rdataset_isassociated(&val->frdataset))
00699 dns_rdataset_expire(&val->frdataset);
00700 if (dns_rdataset_isassociated(&val->fsigrdataset))
00701 dns_rdataset_expire(&val->fsigrdataset);
00702 }
00703 validator_log(val, ISC_LOG_DEBUG(3),
00704 "keyvalidated: got %s",
00705 isc_result_totext(eresult));
00706 validator_done(val, DNS_R_BROKENCHAIN);
00707 }
00708 want_destroy = exit_check(val);
00709 UNLOCK(&val->lock);
00710 if (want_destroy)
00711 destroy(val);
00712 }
00713
00714
00715
00716
00717
00718
00719 static void
00720 dsvalidated(isc_task_t *task, isc_event_t *event) {
00721 dns_validatorevent_t *devent;
00722 dns_validator_t *val;
00723 isc_boolean_t want_destroy;
00724 isc_result_t result;
00725 isc_result_t eresult;
00726
00727 UNUSED(task);
00728 INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
00729
00730 devent = (dns_validatorevent_t *)event;
00731 val = devent->ev_arg;
00732 eresult = devent->result;
00733
00734 isc_event_free(&event);
00735 dns_validator_destroy(&val->subvalidator);
00736
00737 INSIST(val->event != NULL);
00738
00739 validator_log(val, ISC_LOG_DEBUG(3), "in dsvalidated");
00740 LOCK(&val->lock);
00741 if (CANCELED(val)) {
00742 validator_done(val, ISC_R_CANCELED);
00743 } else if (eresult == ISC_R_SUCCESS) {
00744 isc_boolean_t have_dsset;
00745 dns_name_t *name;
00746 validator_log(val, ISC_LOG_DEBUG(3),
00747 "%s with trust %s",
00748 val->frdataset.type == dns_rdatatype_ds ?
00749 "dsset" : "ds non-existance",
00750 dns_trust_totext(val->frdataset.trust));
00751 have_dsset = ISC_TF(val->frdataset.type == dns_rdatatype_ds);
00752 name = dns_fixedname_name(&val->fname);
00753 if ((val->attributes & VALATTR_INSECURITY) != 0 &&
00754 val->frdataset.covers == dns_rdatatype_ds &&
00755 NEGATIVE(&val->frdataset) &&
00756 isdelegation(name, &val->frdataset, DNS_R_NCACHENXRRSET)) {
00757 if (val->mustbesecure) {
00758 validator_log(val, ISC_LOG_WARNING,
00759 "must be secure failure, no DS "
00760 "and this is a delegation");
00761 result = DNS_R_MUSTBESECURE;
00762 } else if (val->view->dlv == NULL || DLVTRIED(val)) {
00763 markanswer(val, "dsvalidated");
00764 result = ISC_R_SUCCESS;;
00765 } else
00766 result = startfinddlvsep(val, name);
00767 } else if ((val->attributes & VALATTR_INSECURITY) != 0) {
00768 result = proveunsecure(val, have_dsset, ISC_TRUE);
00769 } else
00770 result = validatezonekey(val);
00771 if (result != DNS_R_WAIT)
00772 validator_done(val, result);
00773 } else {
00774 if (eresult != DNS_R_BROKENCHAIN) {
00775 if (dns_rdataset_isassociated(&val->frdataset))
00776 dns_rdataset_expire(&val->frdataset);
00777 if (dns_rdataset_isassociated(&val->fsigrdataset))
00778 dns_rdataset_expire(&val->fsigrdataset);
00779 }
00780 validator_log(val, ISC_LOG_DEBUG(3),
00781 "dsvalidated: got %s",
00782 isc_result_totext(eresult));
00783 validator_done(val, DNS_R_BROKENCHAIN);
00784 }
00785 want_destroy = exit_check(val);
00786 UNLOCK(&val->lock);
00787 if (want_destroy)
00788 destroy(val);
00789 }
00790
00791
00792
00793
00794
00795
00796 static void
00797 cnamevalidated(isc_task_t *task, isc_event_t *event) {
00798 dns_validatorevent_t *devent;
00799 dns_validator_t *val;
00800 isc_boolean_t want_destroy;
00801 isc_result_t result;
00802 isc_result_t eresult;
00803
00804 UNUSED(task);
00805 INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
00806
00807 devent = (dns_validatorevent_t *)event;
00808 val = devent->ev_arg;
00809 eresult = devent->result;
00810
00811 isc_event_free(&event);
00812 dns_validator_destroy(&val->subvalidator);
00813
00814 INSIST(val->event != NULL);
00815 INSIST((val->attributes & VALATTR_INSECURITY) != 0);
00816
00817 validator_log(val, ISC_LOG_DEBUG(3), "in cnamevalidated");
00818 LOCK(&val->lock);
00819 if (CANCELED(val)) {
00820 validator_done(val, ISC_R_CANCELED);
00821 } else if (eresult == ISC_R_SUCCESS) {
00822 validator_log(val, ISC_LOG_DEBUG(3), "cname with trust %s",
00823 dns_trust_totext(val->frdataset.trust));
00824 result = proveunsecure(val, ISC_FALSE, ISC_TRUE);
00825 if (result != DNS_R_WAIT)
00826 validator_done(val, result);
00827 } else {
00828 if (eresult != DNS_R_BROKENCHAIN) {
00829 if (dns_rdataset_isassociated(&val->frdataset))
00830 dns_rdataset_expire(&val->frdataset);
00831 if (dns_rdataset_isassociated(&val->fsigrdataset))
00832 dns_rdataset_expire(&val->fsigrdataset);
00833 }
00834 validator_log(val, ISC_LOG_DEBUG(3),
00835 "cnamevalidated: got %s",
00836 isc_result_totext(eresult));
00837 validator_done(val, DNS_R_BROKENCHAIN);
00838 }
00839 want_destroy = exit_check(val);
00840 UNLOCK(&val->lock);
00841 if (want_destroy)
00842 destroy(val);
00843 }
00844
00845
00846
00847
00848
00849
00850
00851
00852 static void
00853 authvalidated(isc_task_t *task, isc_event_t *event) {
00854 dns_validatorevent_t *devent;
00855 dns_validator_t *val;
00856 dns_rdataset_t *rdataset;
00857 isc_boolean_t want_destroy;
00858 isc_result_t result;
00859 isc_boolean_t exists, data;
00860
00861 UNUSED(task);
00862 INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
00863
00864 devent = (dns_validatorevent_t *)event;
00865 rdataset = devent->rdataset;
00866 val = devent->ev_arg;
00867 result = devent->result;
00868 dns_validator_destroy(&val->subvalidator);
00869
00870 INSIST(val->event != NULL);
00871
00872 validator_log(val, ISC_LOG_DEBUG(3), "in authvalidated");
00873 LOCK(&val->lock);
00874 if (CANCELED(val)) {
00875 validator_done(val, ISC_R_CANCELED);
00876 } else if (result != ISC_R_SUCCESS) {
00877 validator_log(val, ISC_LOG_DEBUG(3),
00878 "authvalidated: got %s",
00879 isc_result_totext(result));
00880 if (result == DNS_R_BROKENCHAIN)
00881 val->authfail++;
00882 if (result == ISC_R_CANCELED)
00883 validator_done(val, result);
00884 else {
00885 result = nsecvalidate(val, ISC_TRUE);
00886 if (result != DNS_R_WAIT)
00887 validator_done(val, result);
00888 }
00889 } else {
00890 dns_name_t **proofs = val->event->proofs;
00891 dns_name_t *wild = dns_fixedname_name(&val->wild);
00892
00893 if (rdataset->trust == dns_trust_secure)
00894 val->seensig = ISC_TRUE;
00895
00896 if (rdataset->type == dns_rdatatype_nsec &&
00897 rdataset->trust == dns_trust_secure &&
00898 (NEEDNODATA(val) || NEEDNOQNAME(val)) &&
00899 !FOUNDNODATA(val) && !FOUNDNOQNAME(val) &&
00900 dns_nsec_noexistnodata(val->event->type, val->event->name,
00901 devent->name, rdataset, &exists,
00902 &data, wild, validator_log, val)
00903 == ISC_R_SUCCESS)
00904 {
00905 if (exists && !data) {
00906 val->attributes |= VALATTR_FOUNDNODATA;
00907 if (NEEDNODATA(val))
00908 proofs[DNS_VALIDATOR_NODATAPROOF] =
00909 devent->name;
00910 }
00911 if (!exists) {
00912 dns_name_t *closest;
00913 unsigned int clabels;
00914
00915 val->attributes |= VALATTR_FOUNDNOQNAME;
00916
00917 closest = dns_fixedname_name(&val->closest);
00918 clabels = dns_name_countlabels(closest);
00919
00920
00921
00922
00923
00924
00925
00926 if (clabels == 0 ||
00927 dns_name_countlabels(wild) == clabels + 1)
00928 val->attributes |= VALATTR_FOUNDCLOSEST;
00929
00930
00931
00932
00933 if (NEEDNOQNAME(val))
00934 proofs[DNS_VALIDATOR_NOQNAMEPROOF] =
00935 devent->name;
00936 }
00937 }
00938
00939 result = nsecvalidate(val, ISC_TRUE);
00940 if (result != DNS_R_WAIT)
00941 validator_done(val, result);
00942 }
00943 want_destroy = exit_check(val);
00944 UNLOCK(&val->lock);
00945 if (want_destroy)
00946 destroy(val);
00947
00948
00949
00950
00951 isc_event_free(&event);
00952 }
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969 static inline isc_result_t
00970 view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) {
00971 dns_fixedname_t fixedname;
00972 dns_name_t *foundname;
00973 dns_rdata_nsec_t nsec;
00974 dns_rdata_t rdata = DNS_RDATA_INIT;
00975 isc_result_t result;
00976 unsigned int options;
00977 isc_time_t now;
00978 char buf1[DNS_NAME_FORMATSIZE];
00979 char buf2[DNS_NAME_FORMATSIZE];
00980 char buf3[DNS_NAME_FORMATSIZE];
00981 char namebuf[DNS_NAME_FORMATSIZE];
00982 char typebuf[DNS_RDATATYPE_FORMATSIZE];
00983
00984 if (dns_rdataset_isassociated(&val->frdataset))
00985 dns_rdataset_disassociate(&val->frdataset);
00986 if (dns_rdataset_isassociated(&val->fsigrdataset))
00987 dns_rdataset_disassociate(&val->fsigrdataset);
00988
00989 if (isc_time_now(&now) == ISC_R_SUCCESS &&
00990 dns_resolver_getbadcache(val->view->resolver, name, type, &now)) {
00991
00992 dns_name_format(name, namebuf, sizeof(namebuf));
00993 dns_rdatatype_format(type, typebuf, sizeof(typebuf));
00994 validator_log(val, ISC_LOG_INFO, "bad cache hit (%s/%s)",
00995 namebuf, typebuf);
00996 return (DNS_R_BROKENCHAIN);
00997 }
00998
00999 options = DNS_DBFIND_PENDINGOK;
01000 if (type == dns_rdatatype_dlv)
01001 options |= DNS_DBFIND_COVERINGNSEC;
01002 dns_fixedname_init(&fixedname);
01003 foundname = dns_fixedname_name(&fixedname);
01004 result = dns_view_find(val->view, name, type, 0, options,
01005 ISC_FALSE, NULL, NULL, foundname,
01006 &val->frdataset, &val->fsigrdataset);
01007
01008 if (result == DNS_R_NXDOMAIN) {
01009 if (dns_rdataset_isassociated(&val->frdataset))
01010 dns_rdataset_disassociate(&val->frdataset);
01011 if (dns_rdataset_isassociated(&val->fsigrdataset))
01012 dns_rdataset_disassociate(&val->fsigrdataset);
01013 } else if (result == DNS_R_COVERINGNSEC) {
01014 validator_log(val, ISC_LOG_DEBUG(3), "DNS_R_COVERINGNSEC");
01015
01016
01017
01018 INSIST(type == dns_rdatatype_dlv);
01019 if (val->frdataset.trust != dns_trust_secure) {
01020 validator_log(val, ISC_LOG_DEBUG(3),
01021 "covering nsec: trust %s",
01022 dns_trust_totext(val->frdataset.trust));
01023 goto notfound;
01024 }
01025 result = dns_rdataset_first(&val->frdataset);
01026 if (result != ISC_R_SUCCESS)
01027 goto notfound;
01028 dns_rdataset_current(&val->frdataset, &rdata);
01029 if (dns_nsec_typepresent(&rdata, dns_rdatatype_ns) &&
01030 !dns_nsec_typepresent(&rdata, dns_rdatatype_soa)) {
01031
01032 if (dns_name_issubdomain(name, foundname)) {
01033 validator_log(val, ISC_LOG_DEBUG(3),
01034 "covering nsec: for parent");
01035 goto notfound;
01036 }
01037 }
01038 result = dns_rdata_tostruct(&rdata, &nsec, NULL);
01039 if (result != ISC_R_SUCCESS)
01040 goto notfound;
01041 if (dns_name_compare(foundname, &nsec.next) >= 0) {
01042
01043 if (!dns_name_issubdomain(name, &nsec.next)) {
01044
01045
01046
01047
01048
01049 dns_rdata_freestruct(&nsec);
01050 validator_log(val, ISC_LOG_DEBUG(3),
01051 "covering nsec: not in zone");
01052 goto notfound;
01053 }
01054 } else if (dns_name_compare(name, &nsec.next) >= 0) {
01055
01056
01057
01058
01059
01060
01061
01062 dns_rdata_freestruct(&nsec);
01063 validator_log(val, ISC_LOG_DEBUG(3),
01064 "covering nsec: not in range");
01065 goto notfound;
01066 }
01067 if (isc_log_wouldlog(dns_lctx,ISC_LOG_DEBUG(3))) {
01068 dns_name_format(name, buf1, sizeof buf1);
01069 dns_name_format(foundname, buf2, sizeof buf2);
01070 dns_name_format(&nsec.next, buf3, sizeof buf3);
01071 validator_log(val, ISC_LOG_DEBUG(3),
01072 "covering nsec found: '%s' '%s' '%s'",
01073 buf1, buf2, buf3);
01074 }
01075 if (dns_rdataset_isassociated(&val->frdataset))
01076 dns_rdataset_disassociate(&val->frdataset);
01077 if (dns_rdataset_isassociated(&val->fsigrdataset))
01078 dns_rdataset_disassociate(&val->fsigrdataset);
01079 dns_rdata_freestruct(&nsec);
01080 result = DNS_R_NCACHENXDOMAIN;
01081 } else if (result != ISC_R_SUCCESS &&
01082 result != DNS_R_NCACHENXDOMAIN &&
01083 result != DNS_R_NCACHENXRRSET &&
01084 result != DNS_R_EMPTYNAME &&
01085 result != DNS_R_NXRRSET &&
01086 result != ISC_R_NOTFOUND) {
01087 goto notfound;
01088 }
01089 return (result);
01090
01091 notfound:
01092 if (dns_rdataset_isassociated(&val->frdataset))
01093 dns_rdataset_disassociate(&val->frdataset);
01094 if (dns_rdataset_isassociated(&val->fsigrdataset))
01095 dns_rdataset_disassociate(&val->fsigrdataset);
01096 return (ISC_R_NOTFOUND);
01097 }
01098
01099
01100
01101
01102
01103 static inline isc_boolean_t
01104 check_deadlock(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
01105 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
01106 {
01107 dns_validator_t *parent;
01108
01109 for (parent = val; parent != NULL; parent = parent->parent) {
01110 if (parent->event != NULL &&
01111 parent->event->type == type &&
01112 dns_name_equal(parent->event->name, name) &&
01113
01114
01115
01116
01117
01118 (parent->event->type != dns_rdatatype_nsec3 ||
01119 rdataset == NULL || sigrdataset == NULL ||
01120 parent->event->message == NULL ||
01121 parent->event->rdataset != NULL ||
01122 parent->event->sigrdataset != NULL))
01123 {
01124 validator_log(val, ISC_LOG_DEBUG(3),
01125 "continuing validation would lead to "
01126 "deadlock: aborting validation");
01127 return (ISC_TRUE);
01128 }
01129 }
01130 return (ISC_FALSE);
01131 }
01132
01133
01134
01135
01136 static inline isc_result_t
01137 create_fetch(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
01138 isc_taskaction_t callback, const char *caller)
01139 {
01140 unsigned int fopts = 0;
01141
01142 if (dns_rdataset_isassociated(&val->frdataset))
01143 dns_rdataset_disassociate(&val->frdataset);
01144 if (dns_rdataset_isassociated(&val->fsigrdataset))
01145 dns_rdataset_disassociate(&val->fsigrdataset);
01146
01147 if (check_deadlock(val, name, type, NULL, NULL)) {
01148 validator_log(val, ISC_LOG_DEBUG(3),
01149 "deadlock found (create_fetch)");
01150 return (DNS_R_NOVALIDSIG);
01151 }
01152
01153 if ((val->options & DNS_VALIDATOR_NOCDFLAG) != 0)
01154 fopts |= DNS_FETCHOPT_NOCDFLAG;
01155
01156 if ((val->options & DNS_VALIDATOR_NONTA) != 0)
01157 fopts |= DNS_FETCHOPT_NONTA;
01158
01159 validator_logcreate(val, name, type, caller, "fetch");
01160 return (dns_resolver_createfetch(val->view->resolver, name, type,
01161 NULL, NULL, NULL, fopts,
01162 val->event->ev_sender,
01163 callback, val,
01164 &val->frdataset,
01165 &val->fsigrdataset,
01166 &val->fetch));
01167 }
01168
01169
01170
01171
01172 static inline isc_result_t
01173 create_validator(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
01174 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
01175 isc_taskaction_t action, const char *caller)
01176 {
01177 isc_result_t result;
01178 unsigned int vopts = 0;
01179
01180 if (check_deadlock(val, name, type, rdataset, sigrdataset)) {
01181 validator_log(val, ISC_LOG_DEBUG(3),
01182 "deadlock found (create_validator)");
01183 return (DNS_R_NOVALIDSIG);
01184 }
01185
01186
01187 vopts |= (val->options & (DNS_VALIDATOR_NOCDFLAG|DNS_VALIDATOR_NONTA));
01188
01189 validator_logcreate(val, name, type, caller, "validator");
01190 result = dns_validator_create(val->view, name, type,
01191 rdataset, sigrdataset, NULL, vopts,
01192 val->task, action, val,
01193 &val->subvalidator);
01194 if (result == ISC_R_SUCCESS) {
01195 val->subvalidator->parent = val;
01196 val->subvalidator->depth = val->depth + 1;
01197 }
01198 return (result);
01199 }
01200
01201
01202
01203
01204
01205
01206
01207
01208 static isc_result_t
01209 get_dst_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo,
01210 dns_rdataset_t *rdataset)
01211 {
01212 isc_result_t result;
01213 isc_buffer_t b;
01214 dns_rdata_t rdata = DNS_RDATA_INIT;
01215 dst_key_t *oldkey = val->key;
01216 isc_boolean_t foundold;
01217
01218 if (oldkey == NULL)
01219 foundold = ISC_TRUE;
01220 else {
01221 foundold = ISC_FALSE;
01222 val->key = NULL;
01223 }
01224
01225 result = dns_rdataset_first(rdataset);
01226 if (result != ISC_R_SUCCESS)
01227 goto failure;
01228 do {
01229 dns_rdataset_current(rdataset, &rdata);
01230
01231 isc_buffer_init(&b, rdata.data, rdata.length);
01232 isc_buffer_add(&b, rdata.length);
01233 INSIST(val->key == NULL);
01234 result = dst_key_fromdns(&siginfo->signer, rdata.rdclass, &b,
01235 val->view->mctx, &val->key);
01236 if (result != ISC_R_SUCCESS)
01237 goto failure;
01238 if (siginfo->algorithm ==
01239 (dns_secalg_t)dst_key_alg(val->key) &&
01240 siginfo->keyid ==
01241 (dns_keytag_t)dst_key_id(val->key) &&
01242 dst_key_iszonekey(val->key))
01243 {
01244 if (foundold)
01245
01246
01247
01248 return (ISC_R_SUCCESS);
01249 else if (dst_key_compare(oldkey, val->key) == ISC_TRUE)
01250 {
01251 foundold = ISC_TRUE;
01252 dst_key_free(&oldkey);
01253 }
01254 }
01255 dst_key_free(&val->key);
01256 dns_rdata_reset(&rdata);
01257 result = dns_rdataset_next(rdataset);
01258 } while (result == ISC_R_SUCCESS);
01259 if (result == ISC_R_NOMORE)
01260 result = ISC_R_NOTFOUND;
01261
01262 failure:
01263 if (oldkey != NULL)
01264 dst_key_free(&oldkey);
01265
01266 return (result);
01267 }
01268
01269
01270
01271
01272 static isc_result_t
01273 get_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo) {
01274 isc_result_t result;
01275 unsigned int nlabels;
01276 int order;
01277 dns_namereln_t namereln;
01278
01279
01280
01281
01282
01283
01284
01285 namereln = dns_name_fullcompare(val->event->name, &siginfo->signer,
01286 &order, &nlabels);
01287 if (namereln != dns_namereln_subdomain &&
01288 namereln != dns_namereln_equal)
01289 return (DNS_R_CONTINUE);
01290
01291 if (namereln == dns_namereln_equal) {
01292
01293
01294
01295
01296 if (val->event->rdataset->type == dns_rdatatype_dnskey)
01297 return (DNS_R_CONTINUE);
01298
01299
01300
01301
01302
01303 if (dns_rdatatype_atparent(val->event->rdataset->type))
01304 return (DNS_R_CONTINUE);
01305 } else {
01306
01307
01308
01309
01310 if (val->event->rdataset->type == dns_rdatatype_soa ||
01311 val->event->rdataset->type == dns_rdatatype_ns) {
01312 const char *typename;
01313
01314 if (val->event->rdataset->type == dns_rdatatype_soa)
01315 typename = "SOA";
01316 else
01317 typename = "NS";
01318 validator_log(val, ISC_LOG_DEBUG(3),
01319 "%s signer mismatch", typename);
01320 return (DNS_R_CONTINUE);
01321 }
01322 }
01323
01324
01325
01326
01327 result = view_find(val, &siginfo->signer, dns_rdatatype_dnskey);
01328 if (result == ISC_R_SUCCESS) {
01329
01330
01331
01332 val->keyset = &val->frdataset;
01333 if ((DNS_TRUST_PENDING(val->frdataset.trust) ||
01334 DNS_TRUST_ANSWER(val->frdataset.trust)) &&
01335 dns_rdataset_isassociated(&val->fsigrdataset))
01336 {
01337
01338
01339
01340
01341
01342 result = create_validator(val, &siginfo->signer,
01343 dns_rdatatype_dnskey,
01344 &val->frdataset,
01345 &val->fsigrdataset,
01346 keyvalidated,
01347 "get_key");
01348 if (result != ISC_R_SUCCESS)
01349 return (result);
01350 return (DNS_R_WAIT);
01351 } else if (DNS_TRUST_PENDING(val->frdataset.trust)) {
01352
01353
01354
01355
01356 result = DNS_R_CONTINUE;
01357 } else if (val->frdataset.trust < dns_trust_secure) {
01358
01359
01360
01361
01362 val->key = NULL;
01363 result = ISC_R_SUCCESS;
01364 } else {
01365
01366
01367
01368 validator_log(val, ISC_LOG_DEBUG(3),
01369 "keyset with trust %s",
01370 dns_trust_totext(val->frdataset.trust));
01371 result = get_dst_key(val, siginfo, val->keyset);
01372 if (result != ISC_R_SUCCESS) {
01373
01374
01375
01376
01377
01378 result = DNS_R_CONTINUE;
01379 }
01380 }
01381 } else if (result == ISC_R_NOTFOUND) {
01382
01383
01384
01385 result = create_fetch(val, &siginfo->signer,
01386 dns_rdatatype_dnskey,
01387 fetch_callback_validator, "get_key");
01388 if (result != ISC_R_SUCCESS)
01389 return (result);
01390 return (DNS_R_WAIT);
01391 } else if (result == DNS_R_NCACHENXDOMAIN ||
01392 result == DNS_R_NCACHENXRRSET ||
01393 result == DNS_R_EMPTYNAME ||
01394 result == DNS_R_NXDOMAIN ||
01395 result == DNS_R_NXRRSET)
01396 {
01397
01398
01399
01400 result = DNS_R_CONTINUE;
01401 } else if (result == DNS_R_BROKENCHAIN)
01402 return (result);
01403
01404 if (dns_rdataset_isassociated(&val->frdataset) &&
01405 val->keyset != &val->frdataset)
01406 dns_rdataset_disassociate(&val->frdataset);
01407 if (dns_rdataset_isassociated(&val->fsigrdataset))
01408 dns_rdataset_disassociate(&val->fsigrdataset);
01409
01410 return (result);
01411 }
01412
01413 static dns_keytag_t
01414 compute_keytag(dns_rdata_t *rdata, dns_rdata_dnskey_t *key) {
01415 isc_region_t r;
01416
01417 dns_rdata_toregion(rdata, &r);
01418 return (dst_region_computeid(&r, key->algorithm));
01419 }
01420
01421
01422
01423
01424 static isc_boolean_t
01425 isselfsigned(dns_validator_t *val) {
01426 dns_fixedname_t fixed;
01427 dns_rdataset_t *rdataset, *sigrdataset;
01428 dns_rdata_t rdata = DNS_RDATA_INIT;
01429 dns_rdata_t sigrdata = DNS_RDATA_INIT;
01430 dns_rdata_dnskey_t key;
01431 dns_rdata_rrsig_t sig;
01432 dns_keytag_t keytag;
01433 dns_name_t *name;
01434 isc_result_t result;
01435 dst_key_t *dstkey;
01436 isc_mem_t *mctx;
01437 isc_boolean_t answer = ISC_FALSE;
01438
01439 rdataset = val->event->rdataset;
01440 sigrdataset = val->event->sigrdataset;
01441 name = val->event->name;
01442 mctx = val->view->mctx;
01443
01444 if (rdataset->type == dns_rdatatype_cname ||
01445 rdataset->type == dns_rdatatype_dname)
01446 return (answer);
01447
01448 INSIST(rdataset->type == dns_rdatatype_dnskey);
01449
01450 for (result = dns_rdataset_first(rdataset);
01451 result == ISC_R_SUCCESS;
01452 result = dns_rdataset_next(rdataset))
01453 {
01454 dns_rdata_reset(&rdata);
01455 dns_rdataset_current(rdataset, &rdata);
01456 result = dns_rdata_tostruct(&rdata, &key, NULL);
01457 RUNTIME_CHECK(result == ISC_R_SUCCESS);
01458 keytag = compute_keytag(&rdata, &key);
01459 for (result = dns_rdataset_first(sigrdataset);
01460 result == ISC_R_SUCCESS;
01461 result = dns_rdataset_next(sigrdataset))
01462 {
01463 dns_rdata_reset(&sigrdata);
01464 dns_rdataset_current(sigrdataset, &sigrdata);
01465 result = dns_rdata_tostruct(&sigrdata, &sig, NULL);
01466 RUNTIME_CHECK(result == ISC_R_SUCCESS);
01467
01468 if (sig.algorithm != key.algorithm ||
01469 sig.keyid != keytag ||
01470 !dns_name_equal(name, &sig.signer))
01471 continue;
01472
01473 dstkey = NULL;
01474 result = dns_dnssec_keyfromrdata(name, &rdata, mctx,
01475 &dstkey);
01476 if (result != ISC_R_SUCCESS)
01477 continue;
01478
01479 result = dns_dnssec_verify3(name, rdataset, dstkey,
01480 ISC_TRUE,
01481 val->view->maxbits,
01482 mctx, &sigrdata,
01483 dns_fixedname_name(&fixed));
01484 dst_key_free(&dstkey);
01485 if (result != ISC_R_SUCCESS)
01486 continue;
01487 if ((key.flags & DNS_KEYFLAG_REVOKE) == 0) {
01488 answer = ISC_TRUE;
01489 continue;
01490 }
01491 dns_view_untrust(val->view, name, &key, mctx);
01492 }
01493 }
01494 return (answer);
01495 }
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506 static isc_result_t
01507 verify(dns_validator_t *val, dst_key_t *key, dns_rdata_t *rdata,
01508 isc_uint16_t keyid)
01509 {
01510 isc_result_t result;
01511 dns_fixedname_t fixed;
01512 isc_boolean_t ignore = ISC_FALSE;
01513 dns_name_t *wild;
01514
01515 val->attributes |= VALATTR_TRIEDVERIFY;
01516 dns_fixedname_init(&fixed);
01517 wild = dns_fixedname_name(&fixed);
01518 again:
01519 result = dns_dnssec_verify3(val->event->name, val->event->rdataset,
01520 key, ignore, val->view->maxbits,
01521 val->view->mctx, rdata, wild);
01522 if ((result == DNS_R_SIGEXPIRED || result == DNS_R_SIGFUTURE) &&
01523 val->view->acceptexpired)
01524 {
01525 ignore = ISC_TRUE;
01526 goto again;
01527 }
01528 if (ignore && (result == ISC_R_SUCCESS || result == DNS_R_FROMWILDCARD))
01529 validator_log(val, ISC_LOG_INFO,
01530 "accepted expired %sRRSIG (keyid=%u)",
01531 (result == DNS_R_FROMWILDCARD) ?
01532 "wildcard " : "", keyid);
01533 else if (result == DNS_R_SIGEXPIRED || result == DNS_R_SIGFUTURE)
01534 validator_log(val, ISC_LOG_INFO,
01535 "verify failed due to bad signature (keyid=%u): "
01536 "%s", keyid, isc_result_totext(result));
01537 else
01538 validator_log(val, ISC_LOG_DEBUG(3),
01539 "verify rdataset (keyid=%u): %s",
01540 keyid, isc_result_totext(result));
01541 if (result == DNS_R_FROMWILDCARD) {
01542 if (!dns_name_equal(val->event->name, wild)) {
01543 dns_name_t *closest;
01544 unsigned int labels;
01545
01546
01547
01548
01549
01550 closest = dns_fixedname_name(&val->closest);
01551 dns_name_copy(wild, closest, NULL);
01552 labels = dns_name_countlabels(closest) - 1;
01553 dns_name_getlabelsequence(closest, 1, labels, closest);
01554 val->attributes |= VALATTR_NEEDNOQNAME;
01555 }
01556 result = ISC_R_SUCCESS;
01557 }
01558 return (result);
01559 }
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570 static isc_result_t
01571 validate(dns_validator_t *val, isc_boolean_t resume) {
01572 isc_result_t result, vresult = DNS_R_NOVALIDSIG;
01573 dns_validatorevent_t *event;
01574 dns_rdata_t rdata = DNS_RDATA_INIT;
01575
01576
01577
01578
01579
01580 event = val->event;
01581
01582 if (resume) {
01583
01584
01585
01586 result = ISC_R_SUCCESS;
01587 validator_log(val, ISC_LOG_DEBUG(3), "resuming validate");
01588 } else {
01589 result = dns_rdataset_first(event->sigrdataset);
01590 }
01591
01592 for (;
01593 result == ISC_R_SUCCESS;
01594 result = dns_rdataset_next(event->sigrdataset))
01595 {
01596 dns_rdata_reset(&rdata);
01597 dns_rdataset_current(event->sigrdataset, &rdata);
01598 if (val->siginfo == NULL) {
01599 val->siginfo = isc_mem_get(val->view->mctx,
01600 sizeof(*val->siginfo));
01601 if (val->siginfo == NULL)
01602 return (ISC_R_NOMEMORY);
01603 }
01604 result = dns_rdata_tostruct(&rdata, val->siginfo, NULL);
01605 if (result != ISC_R_SUCCESS)
01606 return (result);
01607
01608
01609
01610
01611
01612 if (!dns_resolver_algorithm_supported(val->view->resolver,
01613 event->name,
01614 val->siginfo->algorithm)) {
01615 resume = ISC_FALSE;
01616 continue;
01617 }
01618
01619 if (!resume) {
01620 result = get_key(val, val->siginfo);
01621 if (result == DNS_R_CONTINUE)
01622 continue;
01623 if (result != ISC_R_SUCCESS)
01624 return (result);
01625 }
01626
01627
01628
01629
01630
01631 if (val->key == NULL) {
01632 resume = ISC_FALSE;
01633 continue;
01634 }
01635
01636 do {
01637 vresult = verify(val, val->key, &rdata,
01638 val->siginfo->keyid);
01639 if (vresult == ISC_R_SUCCESS)
01640 break;
01641 if (val->keynode != NULL) {
01642 dns_keynode_t *nextnode = NULL;
01643 result = dns_keytable_findnextkeynode(
01644 val->keytable,
01645 val->keynode,
01646 &nextnode);
01647 dns_keytable_detachkeynode(val->keytable,
01648 &val->keynode);
01649 val->keynode = nextnode;
01650 if (result != ISC_R_SUCCESS) {
01651 val->key = NULL;
01652 break;
01653 }
01654 val->key = dns_keynode_key(val->keynode);
01655 if (val->key == NULL)
01656 break;
01657 } else {
01658 if (get_dst_key(val, val->siginfo, val->keyset)
01659 != ISC_R_SUCCESS)
01660 break;
01661 }
01662 } while (1);
01663 if (vresult != ISC_R_SUCCESS)
01664 validator_log(val, ISC_LOG_DEBUG(3),
01665 "failed to verify rdataset");
01666 else {
01667 dns_rdataset_trimttl(event->rdataset,
01668 event->sigrdataset,
01669 val->siginfo, val->start,
01670 val->view->acceptexpired);
01671 }
01672
01673 if (val->keynode != NULL)
01674 dns_keytable_detachkeynode(val->keytable,
01675 &val->keynode);
01676 else {
01677 if (val->key != NULL)
01678 dst_key_free(&val->key);
01679 if (val->keyset != NULL) {
01680 dns_rdataset_disassociate(val->keyset);
01681 val->keyset = NULL;
01682 }
01683 }
01684 val->key = NULL;
01685 if (NEEDNOQNAME(val)) {
01686 if (val->event->message == NULL) {
01687 validator_log(val, ISC_LOG_DEBUG(3),
01688 "no message available for noqname proof");
01689 return (DNS_R_NOVALIDSIG);
01690 }
01691 validator_log(val, ISC_LOG_DEBUG(3),
01692 "looking for noqname proof");
01693 return (nsecvalidate(val, ISC_FALSE));
01694 } else if (vresult == ISC_R_SUCCESS) {
01695 marksecure(event);
01696 validator_log(val, ISC_LOG_DEBUG(3),
01697 "marking as secure, "
01698 "noqname proof not needed");
01699 return (ISC_R_SUCCESS);
01700 } else {
01701 validator_log(val, ISC_LOG_DEBUG(3),
01702 "verify failure: %s",
01703 isc_result_totext(result));
01704 resume = ISC_FALSE;
01705 }
01706 }
01707 if (result != ISC_R_NOMORE) {
01708 validator_log(val, ISC_LOG_DEBUG(3),
01709 "failed to iterate signatures: %s",
01710 isc_result_totext(result));
01711 return (result);
01712 }
01713
01714 validator_log(val, ISC_LOG_INFO, "no valid signature found");
01715 return (vresult);
01716 }
01717
01718
01719
01720
01721
01722 static isc_result_t
01723 checkkey(dns_validator_t *val, dns_rdata_t *keyrdata, isc_uint16_t keyid,
01724 dns_secalg_t algorithm)
01725 {
01726 dns_rdata_rrsig_t sig;
01727 dst_key_t *dstkey = NULL;
01728 isc_result_t result;
01729
01730 for (result = dns_rdataset_first(val->event->sigrdataset);
01731 result == ISC_R_SUCCESS;
01732 result = dns_rdataset_next(val->event->sigrdataset))
01733 {
01734 dns_rdata_t rdata = DNS_RDATA_INIT;
01735
01736 dns_rdataset_current(val->event->sigrdataset, &rdata);
01737 result = dns_rdata_tostruct(&rdata, &sig, NULL);
01738 RUNTIME_CHECK(result == ISC_R_SUCCESS);
01739 if (keyid != sig.keyid || algorithm != sig.algorithm)
01740 continue;
01741 if (dstkey == NULL) {
01742 result = dns_dnssec_keyfromrdata(val->event->name,
01743 keyrdata,
01744 val->view->mctx,
01745 &dstkey);
01746 if (result != ISC_R_SUCCESS)
01747
01748
01749
01750 continue;
01751 }
01752 result = verify(val, dstkey, &rdata, sig.keyid);
01753 if (result == ISC_R_SUCCESS)
01754 break;
01755 }
01756 if (dstkey != NULL)
01757 dst_key_free(&dstkey);
01758 return (result);
01759 }
01760
01761
01762
01763
01764 static isc_result_t
01765 keyfromds(dns_validator_t *val, dns_rdataset_t *rdataset, dns_rdata_t *dsrdata,
01766 isc_uint8_t digest, isc_uint16_t keyid, dns_secalg_t algorithm,
01767 dns_rdata_t *keyrdata)
01768 {
01769 dns_keytag_t keytag;
01770 dns_rdata_dnskey_t key;
01771 isc_result_t result;
01772 unsigned char dsbuf[DNS_DS_BUFFERSIZE];
01773
01774 for (result = dns_rdataset_first(rdataset);
01775 result == ISC_R_SUCCESS;
01776 result = dns_rdataset_next(rdataset))
01777 {
01778 dns_rdata_t newdsrdata = DNS_RDATA_INIT;
01779
01780 dns_rdata_reset(keyrdata);
01781 dns_rdataset_current(rdataset, keyrdata);
01782 result = dns_rdata_tostruct(keyrdata, &key, NULL);
01783 RUNTIME_CHECK(result == ISC_R_SUCCESS);
01784 keytag = compute_keytag(keyrdata, &key);
01785 if (keyid != keytag || algorithm != key.algorithm)
01786 continue;
01787 dns_rdata_reset(&newdsrdata);
01788 result = dns_ds_buildrdata(val->event->name, keyrdata, digest,
01789 dsbuf, &newdsrdata);
01790 if (result != ISC_R_SUCCESS) {
01791 validator_log(val, ISC_LOG_DEBUG(3),
01792 "dns_ds_buildrdata() -> %s",
01793 dns_result_totext(result));
01794 continue;
01795 }
01796 if (dns_rdata_compare(dsrdata, &newdsrdata) == 0)
01797 break;
01798 }
01799 return (result);
01800 }
01801
01802
01803
01804
01805
01806 static isc_result_t
01807 dlv_validatezonekey(dns_validator_t *val) {
01808 dns_rdata_dlv_t dlv;
01809 dns_rdata_t dlvrdata = DNS_RDATA_INIT;
01810 dns_rdata_t keyrdata = DNS_RDATA_INIT;
01811 dns_rdataset_t trdataset;
01812 isc_boolean_t supported_algorithm;
01813 isc_result_t result;
01814 char digest_types[256];
01815
01816 validator_log(val, ISC_LOG_DEBUG(3), "dlv_validatezonekey");
01817
01818
01819
01820
01821
01822
01823 supported_algorithm = ISC_FALSE;
01824
01825
01826
01827
01828
01829
01830
01831 memset(digest_types, 1, sizeof(digest_types));
01832 for (result = dns_rdataset_first(&val->dlv);
01833 result == ISC_R_SUCCESS;
01834 result = dns_rdataset_next(&val->dlv)) {
01835 dns_rdata_reset(&dlvrdata);
01836 dns_rdataset_current(&val->dlv, &dlvrdata);
01837 result = dns_rdata_tostruct(&dlvrdata, &dlv, NULL);
01838 RUNTIME_CHECK(result == ISC_R_SUCCESS);
01839
01840 if (!dns_resolver_algorithm_supported(val->view->resolver,
01841 val->event->name,
01842 dlv.algorithm))
01843 continue;
01844
01845 if (dlv.digest_type == DNS_DSDIGEST_SHA256 &&
01846 dlv.length == ISC_SHA256_DIGESTLENGTH) {
01847 digest_types[DNS_DSDIGEST_SHA1] = 0;
01848 break;
01849 }
01850 }
01851
01852 for (result = dns_rdataset_first(&val->dlv);
01853 result == ISC_R_SUCCESS;
01854 result = dns_rdataset_next(&val->dlv))
01855 {
01856 dns_rdata_reset(&dlvrdata);
01857 dns_rdataset_current(&val->dlv, &dlvrdata);
01858 result = dns_rdata_tostruct(&dlvrdata, &dlv, NULL);
01859 RUNTIME_CHECK(result == ISC_R_SUCCESS);
01860
01861 if (digest_types[dlv.digest_type] == 0)
01862 continue;
01863
01864 if (!dns_resolver_ds_digest_supported(val->view->resolver,
01865 val->event->name,
01866 dlv.digest_type))
01867 continue;
01868
01869 if (!dns_resolver_algorithm_supported(val->view->resolver,
01870 val->event->name,
01871 dlv.algorithm))
01872 continue;
01873
01874 supported_algorithm = ISC_TRUE;
01875
01876 dns_rdataset_init(&trdataset);
01877 dns_rdataset_clone(val->event->rdataset, &trdataset);
01878
01879
01880
01881
01882 dlvrdata.type = dns_rdatatype_ds;
01883 result = keyfromds(val, &trdataset, &dlvrdata,
01884 dlv.digest_type, dlv.key_tag,
01885 dlv.algorithm, &keyrdata);
01886 if (result != ISC_R_SUCCESS) {
01887 dns_rdataset_disassociate(&trdataset);
01888 validator_log(val, ISC_LOG_DEBUG(3),
01889 "no DNSKEY matching DLV");
01890 continue;
01891 }
01892
01893 validator_log(val, ISC_LOG_DEBUG(3),
01894 "Found matching DLV record: checking for signature");
01895
01896
01897
01898 result = checkkey(val, &keyrdata, dlv.key_tag, dlv.algorithm);
01899
01900 dns_rdataset_disassociate(&trdataset);
01901 if (result == ISC_R_SUCCESS)
01902 break;
01903 validator_log(val, ISC_LOG_DEBUG(3),
01904 "no RRSIG matching DLV key");
01905 }
01906 if (result == ISC_R_SUCCESS) {
01907 marksecure(val->event);
01908 validator_log(val, ISC_LOG_DEBUG(3), "marking as secure (dlv)");
01909 return (result);
01910 } else if (result == ISC_R_NOMORE && !supported_algorithm) {
01911 if (val->mustbesecure) {
01912 validator_log(val, ISC_LOG_WARNING,
01913 "must be secure failure,"
01914 "no supported algorithm/digest (dlv)");
01915 return (DNS_R_MUSTBESECURE);
01916 }
01917 validator_log(val, ISC_LOG_DEBUG(3),
01918 "no supported algorithm/digest (dlv)");
01919 markanswer(val, "dlv_validatezonekey (2)");
01920 return (ISC_R_SUCCESS);
01921 } else
01922 return (DNS_R_NOVALIDSIG);
01923 }
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935 static isc_result_t
01936 validatezonekey(dns_validator_t *val) {
01937 isc_result_t result;
01938 dns_validatorevent_t *event;
01939 dns_rdataset_t trdataset;
01940 dns_rdata_t dsrdata = DNS_RDATA_INIT;
01941 dns_rdata_t keyrdata = DNS_RDATA_INIT;
01942 dns_rdata_t sigrdata = DNS_RDATA_INIT;
01943 char namebuf[DNS_NAME_FORMATSIZE];
01944 dns_rdata_ds_t ds;
01945 dns_rdata_rrsig_t sig;
01946 dst_key_t *dstkey;
01947 isc_boolean_t supported_algorithm;
01948 isc_boolean_t atsep = ISC_FALSE;
01949 char digest_types[256];
01950
01951
01952
01953
01954
01955 event = val->event;
01956
01957 if (val->havedlvsep && val->dlv.trust >= dns_trust_secure &&
01958 dns_name_equal(event->name, dns_fixedname_name(&val->dlvsep)))
01959 return (dlv_validatezonekey(val));
01960
01961 if (val->dsset == NULL) {
01962
01963
01964
01965
01966
01967
01968
01969
01970 if (val->havedlvsep)
01971 goto find_ds;
01972
01973
01974
01975
01976 for (result = dns_rdataset_first(val->event->sigrdataset);
01977 result == ISC_R_SUCCESS;
01978 result = dns_rdataset_next(val->event->sigrdataset))
01979 {
01980 dns_keynode_t *keynode = NULL;
01981 dns_fixedname_t fixed;
01982 dns_name_t *found;
01983
01984 dns_fixedname_init(&fixed);
01985 found = dns_fixedname_name(&fixed);
01986 dns_rdata_reset(&sigrdata);
01987 dns_rdataset_current(val->event->sigrdataset,
01988 &sigrdata);
01989 result = dns_rdata_tostruct(&sigrdata, &sig, NULL);
01990 RUNTIME_CHECK(result == ISC_R_SUCCESS);
01991
01992 if (!dns_name_equal(val->event->name, &sig.signer))
01993 continue;
01994
01995 result = dns_keytable_findkeynode(val->keytable,
01996 val->event->name,
01997 sig.algorithm,
01998 sig.keyid, &keynode);
01999 if (result == ISC_R_NOTFOUND &&
02000 dns_keytable_finddeepestmatch(val->keytable,
02001 val->event->name, found) != ISC_R_SUCCESS) {
02002 if (val->mustbesecure) {
02003 validator_log(val, ISC_LOG_WARNING,
02004 "must be secure failure, "
02005 "not beneath secure root");
02006 return (DNS_R_MUSTBESECURE);
02007 } else
02008 validator_log(val, ISC_LOG_DEBUG(3),
02009 "not beneath secure root");
02010 if (val->view->dlv == NULL) {
02011 markanswer(val, "validatezonekey (1)");
02012 return (ISC_R_SUCCESS);
02013 }
02014 return (startfinddlvsep(val, dns_rootname));
02015 }
02016 if (result == DNS_R_PARTIALMATCH ||
02017 result == ISC_R_SUCCESS)
02018 atsep = ISC_TRUE;
02019 while (result == ISC_R_SUCCESS) {
02020 dns_keynode_t *nextnode = NULL;
02021 dstkey = dns_keynode_key(keynode);
02022 if (dstkey == NULL) {
02023 dns_keytable_detachkeynode(
02024 val->keytable,
02025 &keynode);
02026 break;
02027 }
02028 result = verify(val, dstkey, &sigrdata,
02029 sig.keyid);
02030 if (result == ISC_R_SUCCESS) {
02031 dns_keytable_detachkeynode(
02032 val->keytable,
02033 &keynode);
02034 break;
02035 }
02036 result = dns_keytable_findnextkeynode(
02037 val->keytable,
02038 keynode,
02039 &nextnode);
02040 dns_keytable_detachkeynode(val->keytable,
02041 &keynode);
02042 keynode = nextnode;
02043 }
02044 if (result == ISC_R_SUCCESS) {
02045 marksecure(event);
02046 validator_log(val, ISC_LOG_DEBUG(3),
02047 "signed by trusted key; "
02048 "marking as secure");
02049 return (result);
02050 }
02051 }
02052
02053 if (atsep) {
02054
02055
02056
02057
02058
02059 dns_name_format(val->event->name, namebuf,
02060 sizeof(namebuf));
02061 validator_log(val, ISC_LOG_NOTICE,
02062 "unable to find a DNSKEY which verifies "
02063 "the DNSKEY RRset and also matches a "
02064 "trusted key for '%s'",
02065 namebuf);
02066 return (DNS_R_NOVALIDKEY);
02067 }
02068
02069
02070
02071
02072
02073 if (dns_name_equal(event->name, dns_rootname)) {
02074 if ((val->attributes & VALATTR_TRIEDVERIFY) != 0) {
02075 validator_log(val, ISC_LOG_DEBUG(3),
02076 "root key failed to validate");
02077 return (DNS_R_NOVALIDSIG);
02078 } else {
02079 validator_log(val, ISC_LOG_DEBUG(3),
02080 "no trusted root key");
02081 return (DNS_R_NOVALIDDS);
02082 }
02083 }
02084 find_ds:
02085
02086
02087
02088 result = view_find(val, val->event->name, dns_rdatatype_ds);
02089 if (result == ISC_R_SUCCESS) {
02090
02091
02092
02093 val->dsset = &val->frdataset;
02094 if ((DNS_TRUST_PENDING(val->frdataset.trust) ||
02095 DNS_TRUST_ANSWER(val->frdataset.trust)) &&
02096 dns_rdataset_isassociated(&val->fsigrdataset))
02097 {
02098 result = create_validator(val,
02099 val->event->name,
02100 dns_rdatatype_ds,
02101 &val->frdataset,
02102 &val->fsigrdataset,
02103 dsvalidated,
02104 "validatezonekey");
02105 if (result != ISC_R_SUCCESS)
02106 return (result);
02107 return (DNS_R_WAIT);
02108 } else if (DNS_TRUST_PENDING(val->frdataset.trust)) {
02109
02110
02111
02112 dns_rdataset_disassociate(&val->frdataset);
02113 validator_log(val, ISC_LOG_DEBUG(2),
02114 "unsigned DS record");
02115 return (DNS_R_NOVALIDSIG);
02116 } else {
02117 result = ISC_R_SUCCESS;
02118 POST(result);
02119 }
02120 } else if (result == ISC_R_NOTFOUND) {
02121
02122
02123
02124 result = create_fetch(val, val->event->name,
02125 dns_rdatatype_ds, dsfetched,
02126 "validatezonekey");
02127 if (result != ISC_R_SUCCESS)
02128 return (result);
02129 return (DNS_R_WAIT);
02130 } else if (result == DNS_R_NCACHENXDOMAIN ||
02131 result == DNS_R_NCACHENXRRSET ||
02132 result == DNS_R_EMPTYNAME ||
02133 result == DNS_R_NXDOMAIN ||
02134 result == DNS_R_NXRRSET ||
02135 result == DNS_R_CNAME)
02136 {
02137
02138
02139
02140 if (dns_rdataset_isassociated(&val->frdataset))
02141 dns_rdataset_disassociate(&val->frdataset);
02142 if (dns_rdataset_isassociated(&val->fsigrdataset))
02143 dns_rdataset_disassociate(&val->fsigrdataset);
02144 validator_log(val, ISC_LOG_DEBUG(2), "no DS record");
02145 return (DNS_R_NOVALIDSIG);
02146 } else if (result == DNS_R_BROKENCHAIN)
02147 return (result);
02148 }
02149
02150
02151
02152
02153 INSIST(val->dsset != NULL);
02154
02155 if (val->dsset->trust < dns_trust_secure) {
02156 if (val->mustbesecure) {
02157 validator_log(val, ISC_LOG_WARNING,
02158 "must be secure failure,"
02159 " insecure DS");
02160 return (DNS_R_MUSTBESECURE);
02161 }
02162 if (val->view->dlv == NULL || DLVTRIED(val)) {
02163 markanswer(val, "validatezonekey (2)");
02164 return (ISC_R_SUCCESS);
02165 }
02166 return (startfinddlvsep(val, val->event->name));
02167 }
02168
02169
02170
02171
02172
02173
02174
02175 supported_algorithm = ISC_FALSE;
02176
02177
02178
02179
02180
02181
02182
02183 memset(digest_types, 1, sizeof(digest_types));
02184 for (result = dns_rdataset_first(val->dsset);
02185 result == ISC_R_SUCCESS;
02186 result = dns_rdataset_next(val->dsset)) {
02187 dns_rdata_reset(&dsrdata);
02188 dns_rdataset_current(val->dsset, &dsrdata);
02189 result = dns_rdata_tostruct(&dsrdata, &ds, NULL);
02190 RUNTIME_CHECK(result == ISC_R_SUCCESS);
02191
02192 if (!dns_resolver_algorithm_supported(val->view->resolver,
02193 val->event->name,
02194 ds.algorithm))
02195 continue;
02196
02197 if (ds.digest_type == DNS_DSDIGEST_SHA256 &&
02198 ds.length == ISC_SHA256_DIGESTLENGTH) {
02199 digest_types[DNS_DSDIGEST_SHA1] = 0;
02200 break;
02201 }
02202 }
02203
02204 for (result = dns_rdataset_first(val->dsset);
02205 result == ISC_R_SUCCESS;
02206 result = dns_rdataset_next(val->dsset))
02207 {
02208 dns_rdata_reset(&dsrdata);
02209 dns_rdataset_current(val->dsset, &dsrdata);
02210 result = dns_rdata_tostruct(&dsrdata, &ds, NULL);
02211 RUNTIME_CHECK(result == ISC_R_SUCCESS);
02212
02213 if (digest_types[ds.digest_type] == 0)
02214 continue;
02215
02216 if (!dns_resolver_ds_digest_supported(val->view->resolver,
02217 val->event->name,
02218 ds.digest_type))
02219 continue;
02220
02221 if (!dns_resolver_algorithm_supported(val->view->resolver,
02222 val->event->name,
02223 ds.algorithm))
02224 continue;
02225
02226 supported_algorithm = ISC_TRUE;
02227
02228 dns_rdataset_init(&trdataset);
02229 dns_rdataset_clone(val->event->rdataset, &trdataset);
02230
02231
02232
02233
02234 result = keyfromds(val, &trdataset, &dsrdata, ds.digest_type,
02235 ds.key_tag, ds.algorithm, &keyrdata);
02236 if (result != ISC_R_SUCCESS) {
02237 dns_rdataset_disassociate(&trdataset);
02238 validator_log(val, ISC_LOG_DEBUG(3),
02239 "no DNSKEY matching DS");
02240 continue;
02241 }
02242
02243
02244
02245
02246 result = checkkey(val, &keyrdata, ds.key_tag, ds.algorithm);
02247
02248 dns_rdataset_disassociate(&trdataset);
02249 if (result == ISC_R_SUCCESS)
02250 break;
02251 validator_log(val, ISC_LOG_DEBUG(3),
02252 "no RRSIG matching DS key");
02253 }
02254 if (result == ISC_R_SUCCESS) {
02255 marksecure(event);
02256 validator_log(val, ISC_LOG_DEBUG(3), "marking as secure (DS)");
02257 return (result);
02258 } else if (result == ISC_R_NOMORE && !supported_algorithm) {
02259 if (val->mustbesecure) {
02260 validator_log(val, ISC_LOG_WARNING,
02261 "must be secure failure, "
02262 "no supported algorithm/digest (DS)");
02263 return (DNS_R_MUSTBESECURE);
02264 }
02265 validator_log(val, ISC_LOG_DEBUG(3),
02266 "no supported algorithm/digest (DS)");
02267 markanswer(val, "validatezonekey (3)");
02268 return (ISC_R_SUCCESS);
02269 } else {
02270 validator_log(val, ISC_LOG_INFO,
02271 "no valid signature found (DS)");
02272 return (DNS_R_NOVALIDSIG);
02273 }
02274 }
02275
02276
02277
02278
02279
02280
02281
02282
02283
02284
02285 static isc_result_t
02286 start_positive_validation(dns_validator_t *val) {
02287
02288
02289
02290 if (val->event->type != dns_rdatatype_dnskey || !isselfsigned(val))
02291 return (validate(val, ISC_FALSE));
02292
02293 return (validatezonekey(val));
02294 }
02295
02296
02297
02298
02299
02300
02301 static isc_result_t
02302 val_rdataset_first(dns_validator_t *val, dns_name_t **namep,
02303 dns_rdataset_t **rdatasetp)
02304 {
02305 dns_message_t *message = val->event->message;
02306 isc_result_t result;
02307
02308 REQUIRE(rdatasetp != NULL);
02309 REQUIRE(namep != NULL);
02310 if (message == NULL) {
02311 REQUIRE(*rdatasetp != NULL);
02312 REQUIRE(*namep != NULL);
02313 } else {
02314 REQUIRE(*rdatasetp == NULL);
02315 REQUIRE(*namep == NULL);
02316 }
02317
02318 if (message != NULL) {
02319 result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
02320 if (result != ISC_R_SUCCESS)
02321 return (result);
02322 dns_message_currentname(message, DNS_SECTION_AUTHORITY, namep);
02323 *rdatasetp = ISC_LIST_HEAD((*namep)->list);
02324 INSIST(*rdatasetp != NULL);
02325 } else {
02326 result = dns_rdataset_first(val->event->rdataset);
02327 if (result == ISC_R_SUCCESS)
02328 dns_ncache_current(val->event->rdataset, *namep,
02329 *rdatasetp);
02330 }
02331 return (result);
02332 }
02333
02334 static isc_result_t
02335 val_rdataset_next(dns_validator_t *val, dns_name_t **namep,
02336 dns_rdataset_t **rdatasetp)
02337 {
02338 dns_message_t *message = val->event->message;
02339 isc_result_t result = ISC_R_SUCCESS;
02340
02341 REQUIRE(rdatasetp != NULL && *rdatasetp != NULL);
02342 REQUIRE(namep != NULL && *namep != NULL);
02343
02344 if (message != NULL) {
02345 dns_rdataset_t *rdataset = *rdatasetp;
02346 rdataset = ISC_LIST_NEXT(rdataset, link);
02347 if (rdataset == NULL) {
02348 *namep = NULL;
02349 result = dns_message_nextname(message,
02350 DNS_SECTION_AUTHORITY);
02351 if (result == ISC_R_SUCCESS) {
02352 dns_message_currentname(message,
02353 DNS_SECTION_AUTHORITY,
02354 namep);
02355 rdataset = ISC_LIST_HEAD((*namep)->list);
02356 INSIST(rdataset != NULL);
02357 }
02358 }
02359 *rdatasetp = rdataset;
02360 } else {
02361 dns_rdataset_disassociate(*rdatasetp);
02362 result = dns_rdataset_next(val->event->rdataset);
02363 if (result == ISC_R_SUCCESS)
02364 dns_ncache_current(val->event->rdataset, *namep,
02365 *rdatasetp);
02366 }
02367 return (result);
02368 }
02369
02370
02371
02372
02373
02374
02375
02376
02377
02378 static isc_result_t
02379 checkwildcard(dns_validator_t *val, dns_rdatatype_t type, dns_name_t *zonename)
02380 {
02381 dns_name_t *name, *wild, tname;
02382 isc_result_t result;
02383 isc_boolean_t exists, data;
02384 char namebuf[DNS_NAME_FORMATSIZE];
02385 dns_rdataset_t *rdataset, trdataset;
02386
02387 dns_name_init(&tname, NULL);
02388 dns_rdataset_init(&trdataset);
02389 wild = dns_fixedname_name(&val->wild);
02390
02391 if (dns_name_countlabels(wild) == 0) {
02392 validator_log(val, ISC_LOG_DEBUG(3),
02393 "in checkwildcard: no wildcard to check");
02394 return (ISC_R_SUCCESS);
02395 }
02396
02397 dns_name_format(wild, namebuf, sizeof(namebuf));
02398 validator_log(val, ISC_LOG_DEBUG(3), "in checkwildcard: %s", namebuf);
02399
02400 if (val->event->message == NULL) {
02401 name = &tname;
02402 rdataset = &trdataset;
02403 } else {
02404 name = NULL;
02405 rdataset = NULL;
02406 }
02407
02408 for (result = val_rdataset_first(val, &name, &rdataset);
02409 result == ISC_R_SUCCESS;
02410 result = val_rdataset_next(val, &name, &rdataset))
02411 {
02412 if (rdataset->type != type ||
02413 rdataset->trust != dns_trust_secure)
02414 continue;
02415
02416 if (rdataset->type == dns_rdatatype_nsec &&
02417 (NEEDNODATA(val) || NEEDNOWILDCARD(val)) &&
02418 !FOUNDNODATA(val) && !FOUNDNOWILDCARD(val) &&
02419 dns_nsec_noexistnodata(val->event->type, wild, name,
02420 rdataset, &exists, &data, NULL,
02421 validator_log, val)
02422 == ISC_R_SUCCESS)
02423 {
02424 dns_name_t **proofs = val->event->proofs;
02425 if (exists && !data)
02426 val->attributes |= VALATTR_FOUNDNODATA;
02427 if (exists && !data && NEEDNODATA(val))
02428 proofs[DNS_VALIDATOR_NODATAPROOF] =
02429 name;
02430 if (!exists)
02431 val->attributes |=
02432 VALATTR_FOUNDNOWILDCARD;
02433 if (!exists && NEEDNOQNAME(val))
02434 proofs[DNS_VALIDATOR_NOWILDCARDPROOF] =
02435 name;
02436 if (dns_rdataset_isassociated(&trdataset))
02437 dns_rdataset_disassociate(&trdataset);
02438 return (ISC_R_SUCCESS);
02439 }
02440
02441 if (rdataset->type == dns_rdatatype_nsec3 &&
02442 (NEEDNODATA(val) || NEEDNOWILDCARD(val)) &&
02443 !FOUNDNODATA(val) && !FOUNDNOWILDCARD(val) &&
02444 dns_nsec3_noexistnodata(val->event->type, wild, name,
02445 rdataset, zonename, &exists, &data,
02446 NULL, NULL, NULL, NULL, NULL, NULL,
02447 validator_log, val)
02448 == ISC_R_SUCCESS)
02449 {
02450 dns_name_t **proofs = val->event->proofs;
02451 if (exists && !data)
02452 val->attributes |= VALATTR_FOUNDNODATA;
02453 if (exists && !data && NEEDNODATA(val))
02454 proofs[DNS_VALIDATOR_NODATAPROOF] =
02455 name;
02456 if (!exists)
02457 val->attributes |=
02458 VALATTR_FOUNDNOWILDCARD;
02459 if (!exists && NEEDNOQNAME(val))
02460 proofs[DNS_VALIDATOR_NOWILDCARDPROOF] =
02461 name;
02462 if (dns_rdataset_isassociated(&trdataset))
02463 dns_rdataset_disassociate(&trdataset);
02464 return (ISC_R_SUCCESS);
02465 }
02466 }
02467 if (result == ISC_R_NOMORE)
02468 result = ISC_R_SUCCESS;
02469 if (dns_rdataset_isassociated(&trdataset))
02470 dns_rdataset_disassociate(&trdataset);
02471 return (result);
02472 }
02473
02474 static isc_result_t
02475 findnsec3proofs(dns_validator_t *val) {
02476 dns_name_t *name, tname;
02477 isc_result_t result;
02478 isc_boolean_t exists, data, optout, unknown;
02479 isc_boolean_t setclosest, setnearest, *setclosestp;
02480 dns_fixedname_t fclosest, fnearest, fzonename;
02481 dns_name_t *closest, *nearest, *zonename, *closestp;
02482 dns_name_t **proofs = val->event->proofs;
02483 dns_rdataset_t *rdataset, trdataset;
02484
02485 dns_name_init(&tname, NULL);
02486 dns_rdataset_init(&trdataset);
02487 dns_fixedname_init(&fclosest);
02488 dns_fixedname_init(&fnearest);
02489 dns_fixedname_init(&fzonename);
02490 closest = dns_fixedname_name(&fclosest);
02491 nearest = dns_fixedname_name(&fnearest);
02492 zonename = dns_fixedname_name(&fzonename);
02493
02494 if (val->event->message == NULL) {
02495 name = &tname;
02496 rdataset = &trdataset;
02497 } else {
02498 name = NULL;
02499 rdataset = NULL;
02500 }
02501
02502 for (result = val_rdataset_first(val, &name, &rdataset);
02503 result == ISC_R_SUCCESS;
02504 result = val_rdataset_next(val, &name, &rdataset))
02505 {
02506 if (rdataset->type != dns_rdatatype_nsec3 ||
02507 rdataset->trust != dns_trust_secure)
02508 continue;
02509
02510 result = dns_nsec3_noexistnodata(val->event->type,
02511 val->event->name, name,
02512 rdataset, zonename, NULL,
02513 NULL, NULL, NULL, NULL, NULL,
02514 NULL, NULL, validator_log,
02515 val);
02516 if (result != ISC_R_IGNORE && result != ISC_R_SUCCESS) {
02517 if (dns_rdataset_isassociated(&trdataset))
02518 dns_rdataset_disassociate(&trdataset);
02519 return (result);
02520 }
02521 }
02522 if (result != ISC_R_NOMORE)
02523 result = ISC_R_SUCCESS;
02524 POST(result);
02525
02526 if (dns_name_countlabels(zonename) == 0)
02527 return (ISC_R_SUCCESS);
02528
02529
02530
02531
02532
02533 if (dns_name_countlabels(dns_fixedname_name(&val->closest)) != 0) {
02534 char namebuf[DNS_NAME_FORMATSIZE];
02535
02536 dns_name_format(dns_fixedname_name(&val->closest),
02537 namebuf, sizeof(namebuf));
02538 validator_log(val, ISC_LOG_DEBUG(3), "closest encloser from "
02539 "wildcard signature '%s'", namebuf);
02540 dns_name_copy(dns_fixedname_name(&val->closest), closest, NULL);
02541 closestp = NULL;
02542 setclosestp = NULL;
02543 } else {
02544 closestp = closest;
02545 setclosestp = &setclosest;
02546 }
02547
02548 for (result = val_rdataset_first(val, &name, &rdataset);
02549 result == ISC_R_SUCCESS;
02550 result = val_rdataset_next(val, &name, &rdataset))
02551 {
02552 if (rdataset->type != dns_rdatatype_nsec3 ||
02553 rdataset->trust != dns_trust_secure)
02554 continue;
02555
02556
02557
02558
02559
02560 setclosest = setnearest = ISC_FALSE;
02561 optout = ISC_FALSE;
02562 unknown = ISC_FALSE;
02563 result = dns_nsec3_noexistnodata(val->event->type,
02564 val->event->name,
02565 name, rdataset, zonename,
02566 &exists, &data, &optout,
02567 &unknown, setclosestp,
02568 &setnearest, closestp,
02569 nearest, validator_log, val);
02570 if (unknown)
02571 val->attributes |= VALATTR_FOUNDUNKNOWN;
02572 if (result != ISC_R_SUCCESS)
02573 continue;
02574 if (setclosest)
02575 proofs[DNS_VALIDATOR_CLOSESTENCLOSER] = name;
02576 if (exists && !data && NEEDNODATA(val)) {
02577 val->attributes |= VALATTR_FOUNDNODATA;
02578 proofs[DNS_VALIDATOR_NODATAPROOF] = name;
02579 }
02580 if (!exists && setnearest) {
02581 val->attributes |= VALATTR_FOUNDNOQNAME;
02582 proofs[DNS_VALIDATOR_NOQNAMEPROOF] = name;
02583 if (optout)
02584 val->attributes |= VALATTR_FOUNDOPTOUT;
02585 }
02586 }
02587 if (result == ISC_R_NOMORE)
02588 result = ISC_R_SUCCESS;
02589
02590
02591
02592
02593
02594
02595 if (dns_name_countlabels(closest) > 0 &&
02596 dns_name_countlabels(nearest) ==
02597 dns_name_countlabels(closest) + 1 &&
02598 dns_name_issubdomain(nearest, closest))
02599 {
02600 val->attributes |= VALATTR_FOUNDCLOSEST;
02601 result = dns_name_concatenate(dns_wildcardname, closest,
02602 dns_fixedname_name(&val->wild),
02603 NULL);
02604 RUNTIME_CHECK(result == ISC_R_SUCCESS);
02605 } else {
02606 val->attributes &= ~VALATTR_FOUNDNOQNAME;
02607 val->attributes &= ~VALATTR_FOUNDOPTOUT;
02608 proofs[DNS_VALIDATOR_NOQNAMEPROOF] = NULL;
02609 }
02610
02611
02612
02613
02614 if (FOUNDNOQNAME(val) && FOUNDCLOSEST(val) &&
02615 ((NEEDNODATA(val) && !FOUNDNODATA(val)) || NEEDNOWILDCARD(val))) {
02616 result = checkwildcard(val, dns_rdatatype_nsec3, zonename);
02617 if (result != ISC_R_SUCCESS)
02618 return (result);
02619 }
02620 return (result);
02621 }
02622
02623
02624
02625
02626 static isc_result_t
02627 validate_authority(dns_validator_t *val, isc_boolean_t resume) {
02628 dns_name_t *name;
02629 dns_message_t *message = val->event->message;
02630 isc_result_t result;
02631
02632 if (!resume)
02633 result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
02634 else
02635 result = ISC_R_SUCCESS;
02636
02637 for (;
02638 result == ISC_R_SUCCESS;
02639 result = dns_message_nextname(message, DNS_SECTION_AUTHORITY))
02640 {
02641 dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
02642
02643 name = NULL;
02644 dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name);
02645 if (resume) {
02646 rdataset = ISC_LIST_NEXT(val->currentset, link);
02647 val->currentset = NULL;
02648 resume = ISC_FALSE;
02649 } else
02650 rdataset = ISC_LIST_HEAD(name->list);
02651
02652 for (;
02653 rdataset != NULL;
02654 rdataset = ISC_LIST_NEXT(rdataset, link))
02655 {
02656 if (rdataset->type == dns_rdatatype_rrsig)
02657 continue;
02658
02659 for (sigrdataset = ISC_LIST_HEAD(name->list);
02660 sigrdataset != NULL;
02661 sigrdataset = ISC_LIST_NEXT(sigrdataset,
02662 link))
02663 {
02664 if (sigrdataset->type == dns_rdatatype_rrsig &&
02665 sigrdataset->covers == rdataset->type)
02666 break;
02667 }
02668
02669
02670
02671
02672
02673
02674
02675
02676
02677
02678 if (val->event->type == dns_rdatatype_dnskey &&
02679 rdataset->type == dns_rdatatype_nsec &&
02680 dns_name_equal(name, val->event->name))
02681 {
02682 dns_rdata_t nsec = DNS_RDATA_INIT;
02683
02684 result = dns_rdataset_first(rdataset);
02685 if (result != ISC_R_SUCCESS)
02686 return (result);
02687 dns_rdataset_current(rdataset, &nsec);
02688 if (dns_nsec_typepresent(&nsec,
02689 dns_rdatatype_soa))
02690 continue;
02691 }
02692 val->currentset = rdataset;
02693 result = create_validator(val, name, rdataset->type,
02694 rdataset, sigrdataset,
02695 authvalidated,
02696 "validate_authority");
02697 if (result != ISC_R_SUCCESS)
02698 return (result);
02699 val->authcount++;
02700 return (DNS_R_WAIT);
02701 }
02702 }
02703 if (result == ISC_R_NOMORE)
02704 result = ISC_R_SUCCESS;
02705 return (result);
02706 }
02707
02708
02709
02710
02711 static isc_result_t
02712 validate_ncache(dns_validator_t *val, isc_boolean_t resume) {
02713 dns_name_t *name;
02714 isc_result_t result;
02715
02716 if (!resume)
02717 result = dns_rdataset_first(val->event->rdataset);
02718 else
02719 result = dns_rdataset_next(val->event->rdataset);
02720
02721 for (;
02722 result == ISC_R_SUCCESS;
02723 result = dns_rdataset_next(val->event->rdataset))
02724 {
02725 dns_rdataset_t *rdataset, *sigrdataset = NULL;
02726
02727 if (dns_rdataset_isassociated(&val->frdataset))
02728 dns_rdataset_disassociate(&val->frdataset);
02729 if (dns_rdataset_isassociated(&val->fsigrdataset))
02730 dns_rdataset_disassociate(&val->fsigrdataset);
02731
02732 dns_fixedname_init(&val->fname);
02733 name = dns_fixedname_name(&val->fname);
02734 rdataset = &val->frdataset;
02735 dns_ncache_current(val->event->rdataset, name, rdataset);
02736
02737 if (val->frdataset.type == dns_rdatatype_rrsig)
02738 continue;
02739
02740 result = dns_ncache_getsigrdataset(val->event->rdataset, name,
02741 rdataset->type,
02742 &val->fsigrdataset);
02743 if (result == ISC_R_SUCCESS)
02744 sigrdataset = &val->fsigrdataset;
02745
02746
02747
02748
02749
02750
02751
02752
02753
02754
02755
02756 if (val->event->type == dns_rdatatype_dnskey &&
02757 rdataset->type == dns_rdatatype_nsec &&
02758 dns_name_equal(name, val->event->name))
02759 {
02760 dns_rdata_t nsec = DNS_RDATA_INIT;
02761
02762 result = dns_rdataset_first(rdataset);
02763 if (result != ISC_R_SUCCESS)
02764 return (result);
02765 dns_rdataset_current(rdataset, &nsec);
02766 if (dns_nsec_typepresent(&nsec,
02767 dns_rdatatype_soa))
02768 continue;
02769 }
02770 val->currentset = rdataset;
02771 result = create_validator(val, name, rdataset->type,
02772 rdataset, sigrdataset,
02773 authvalidated,
02774 "validate_ncache");
02775 if (result != ISC_R_SUCCESS)
02776 return (result);
02777 val->authcount++;
02778 return (DNS_R_WAIT);
02779 }
02780 if (result == ISC_R_NOMORE)
02781 result = ISC_R_SUCCESS;
02782 return (result);
02783 }
02784
02785
02786
02787
02788
02789
02790
02791
02792
02793
02794
02795
02796
02797 static isc_result_t
02798 nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
02799 isc_result_t result;
02800
02801 if (resume)
02802 validator_log(val, ISC_LOG_DEBUG(3), "resuming nsecvalidate");
02803
02804 if (val->event->message == NULL)
02805 result = validate_ncache(val, resume);
02806 else
02807 result = validate_authority(val, resume);
02808
02809 if (result != ISC_R_SUCCESS)
02810 return (result);
02811
02812
02813
02814
02815
02816 if (!NEEDNODATA(val) && !NEEDNOWILDCARD(val) && NEEDNOQNAME(val)) {
02817 if (!FOUNDNOQNAME(val))
02818 findnsec3proofs(val);
02819 if (FOUNDNOQNAME(val) && FOUNDCLOSEST(val) &&
02820 !FOUNDOPTOUT(val)) {
02821 validator_log(val, ISC_LOG_DEBUG(3),
02822 "marking as secure, noqname proof found");
02823 marksecure(val->event);
02824 return (ISC_R_SUCCESS);
02825 } else if (FOUNDOPTOUT(val) &&
02826 dns_name_countlabels(dns_fixedname_name(&val->wild))
02827 != 0) {
02828 validator_log(val, ISC_LOG_DEBUG(3),
02829 "optout proof found");
02830 val->event->optout = ISC_TRUE;
02831 markanswer(val, "nsecvalidate (1)");
02832 return (ISC_R_SUCCESS);
02833 } else if ((val->attributes & VALATTR_FOUNDUNKNOWN) != 0) {
02834 validator_log(val, ISC_LOG_DEBUG(3),
02835 "unknown NSEC3 hash algorithm found");
02836 markanswer(val, "nsecvalidate (2)");
02837 return (ISC_R_SUCCESS);
02838 }
02839 validator_log(val, ISC_LOG_DEBUG(3),
02840 "noqname proof not found");
02841 return (DNS_R_NOVALIDNSEC);
02842 }
02843
02844 if (!FOUNDNOQNAME(val) && !FOUNDNODATA(val))
02845 findnsec3proofs(val);
02846
02847
02848
02849
02850 if (FOUNDNOQNAME(val) && FOUNDCLOSEST(val) &&
02851 ((NEEDNODATA(val) && !FOUNDNODATA(val)) || NEEDNOWILDCARD(val))) {
02852 result = checkwildcard(val, dns_rdatatype_nsec, NULL);
02853 if (result != ISC_R_SUCCESS)
02854 return (result);
02855 }
02856
02857 if ((NEEDNODATA(val) && (FOUNDNODATA(val) || FOUNDOPTOUT(val))) ||
02858 (NEEDNOQNAME(val) && FOUNDNOQNAME(val) &&
02859 NEEDNOWILDCARD(val) && FOUNDNOWILDCARD(val) &&
02860 FOUNDCLOSEST(val))) {
02861 if ((val->attributes & VALATTR_FOUNDOPTOUT) != 0)
02862 val->event->optout = ISC_TRUE;
02863 validator_log(val, ISC_LOG_DEBUG(3),
02864 "nonexistence proof(s) found");
02865 if (val->event->message == NULL)
02866 marksecure(val->event);
02867 else
02868 val->event->secure = ISC_TRUE;
02869 return (ISC_R_SUCCESS);
02870 }
02871
02872 if (val->authfail != 0 && val->authcount == val->authfail)
02873 return (DNS_R_BROKENCHAIN);
02874 validator_log(val, ISC_LOG_DEBUG(3),
02875 "nonexistence proof(s) not found");
02876 val->attributes |= VALATTR_INSECURITY;
02877 return (proveunsecure(val, ISC_FALSE, ISC_FALSE));
02878 }
02879
02880 static isc_boolean_t
02881 check_ds(dns_validator_t *val, dns_name_t *name, dns_rdataset_t *rdataset) {
02882 dns_rdata_t dsrdata = DNS_RDATA_INIT;
02883 dns_rdata_ds_t ds;
02884 isc_result_t result;
02885
02886 for (result = dns_rdataset_first(rdataset);
02887 result == ISC_R_SUCCESS;
02888 result = dns_rdataset_next(rdataset)) {
02889 dns_rdataset_current(rdataset, &dsrdata);
02890 result = dns_rdata_tostruct(&dsrdata, &ds, NULL);
02891 RUNTIME_CHECK(result == ISC_R_SUCCESS);
02892
02893 if (dns_resolver_ds_digest_supported(val->view->resolver,
02894 name, ds.digest_type) &&
02895 dns_resolver_algorithm_supported(val->view->resolver,
02896 name, ds.algorithm)) {
02897 dns_rdata_reset(&dsrdata);
02898 return (ISC_TRUE);
02899 }
02900 dns_rdata_reset(&dsrdata);
02901 }
02902 return (ISC_FALSE);
02903 }
02904
02905 static void
02906 dlvvalidated(isc_task_t *task, isc_event_t *event) {
02907 dns_validatorevent_t *devent;
02908 dns_validator_t *val;
02909 isc_result_t eresult;
02910 isc_boolean_t want_destroy;
02911
02912 UNUSED(task);
02913 INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
02914
02915 devent = (dns_validatorevent_t *)event;
02916 val = devent->ev_arg;
02917 eresult = devent->result;
02918
02919 isc_event_free(&event);
02920 dns_validator_destroy(&val->subvalidator);
02921
02922 INSIST(val->event != NULL);
02923
02924 validator_log(val, ISC_LOG_DEBUG(3), "in dlvvalidated");
02925 LOCK(&val->lock);
02926 if (CANCELED(val)) {
02927 validator_done(val, ISC_R_CANCELED);
02928 } else if (eresult == ISC_R_SUCCESS) {
02929 validator_log(val, ISC_LOG_DEBUG(3),
02930 "dlvset with trust %s",
02931 dns_trust_totext(val->frdataset.trust));
02932 dns_rdataset_clone(&val->frdataset, &val->dlv);
02933 val->havedlvsep = ISC_TRUE;
02934 if (dlv_algorithm_supported(val))
02935 dlv_validator_start(val);
02936 else {
02937 markanswer(val, "dlvvalidated");
02938 validator_done(val, ISC_R_SUCCESS);
02939 }
02940 } else {
02941 if (eresult != DNS_R_BROKENCHAIN) {
02942 if (dns_rdataset_isassociated(&val->frdataset))
02943 dns_rdataset_expire(&val->frdataset);
02944 if (dns_rdataset_isassociated(&val->fsigrdataset))
02945 dns_rdataset_expire(&val->fsigrdataset);
02946 }
02947 validator_log(val, ISC_LOG_DEBUG(3),
02948 "dlvvalidated: got %s",
02949 isc_result_totext(eresult));
02950 validator_done(val, DNS_R_BROKENCHAIN);
02951 }
02952 want_destroy = exit_check(val);
02953 UNLOCK(&val->lock);
02954 if (want_destroy)
02955 destroy(val);
02956 }
02957
02958
02959
02960
02961
02962
02963 static void
02964 dlvfetched(isc_task_t *task, isc_event_t *event) {
02965 char namebuf[DNS_NAME_FORMATSIZE];
02966 dns_fetchevent_t *devent;
02967 dns_validator_t *val;
02968 isc_boolean_t want_destroy;
02969 isc_result_t eresult;
02970 isc_result_t result;
02971 dns_fetch_t *fetch;
02972
02973 UNUSED(task);
02974 INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
02975 devent = (dns_fetchevent_t *)event;
02976 val = devent->ev_arg;
02977 eresult = devent->result;
02978
02979
02980 if (devent->node != NULL)
02981 dns_db_detachnode(devent->db, &devent->node);
02982 if (devent->db != NULL)
02983 dns_db_detach(&devent->db);
02984 if (dns_rdataset_isassociated(&val->fsigrdataset))
02985 dns_rdataset_disassociate(&val->fsigrdataset);
02986 isc_event_free(&event);
02987
02988 INSIST(val->event != NULL);
02989 validator_log(val, ISC_LOG_DEBUG(3), "in dlvfetched: %s",
02990 dns_result_totext(eresult));
02991
02992 LOCK(&val->lock);
02993 fetch = val->fetch;
02994 val->fetch = NULL;
02995 if (eresult == ISC_R_SUCCESS) {
02996 dns_name_format(dns_fixedname_name(&val->dlvsep), namebuf,
02997 sizeof(namebuf));
02998 dns_rdataset_clone(&val->frdataset, &val->dlv);
02999 val->havedlvsep = ISC_TRUE;
03000 if (dlv_algorithm_supported(val)) {
03001 validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found",
03002 namebuf);
03003 dlv_validator_start(val);
03004 } else {
03005 validator_log(val, ISC_LOG_DEBUG(3),
03006 "DLV %s found with no supported algorithms",
03007 namebuf);
03008 markanswer(val, "dlvfetched (1)");
03009 validator_done(val, ISC_R_SUCCESS);
03010 }
03011 } else if (eresult == DNS_R_NXRRSET ||
03012 eresult == DNS_R_NXDOMAIN ||
03013 eresult == DNS_R_NCACHENXRRSET ||
03014 eresult == DNS_R_NCACHENXDOMAIN) {
03015 result = finddlvsep(val, ISC_TRUE);
03016 if (result == ISC_R_SUCCESS) {
03017 if (dlv_algorithm_supported(val)) {
03018 dns_name_format(dns_fixedname_name(&val->dlvsep),
03019 namebuf, sizeof(namebuf));
03020 validator_log(val, ISC_LOG_DEBUG(3),
03021 "DLV %s found", namebuf);
03022 dlv_validator_start(val);
03023 } else {
03024 validator_log(val, ISC_LOG_DEBUG(3),
03025 "DLV %s found with no supported "
03026 "algorithms", namebuf);
03027 markanswer(val, "dlvfetched (2)");
03028 validator_done(val, ISC_R_SUCCESS);
03029 }
03030 } else if (result == ISC_R_NOTFOUND) {
03031 validator_log(val, ISC_LOG_DEBUG(3), "DLV not found");
03032 markanswer(val, "dlvfetched (3)");
03033 validator_done(val, ISC_R_SUCCESS);
03034 } else {
03035 validator_log(val, ISC_LOG_DEBUG(3), "DLV lookup: %s",
03036 dns_result_totext(result));
03037 if (result != DNS_R_WAIT)
03038 validator_done(val, result);
03039 }
03040 } else {
03041 validator_log(val, ISC_LOG_DEBUG(3), "DLV lookup: %s",
03042 dns_result_totext(eresult));
03043 validator_done(val, eresult);
03044 }
03045 want_destroy = exit_check(val);
03046 UNLOCK(&val->lock);
03047 if (fetch != NULL)
03048 dns_resolver_destroyfetch(&fetch);
03049 if (want_destroy)
03050 destroy(val);
03051 }
03052
03053
03054
03055
03056
03057
03058
03059
03060
03061 static isc_result_t
03062 startfinddlvsep(dns_validator_t *val, dns_name_t *unsecure) {
03063 char namebuf[DNS_NAME_FORMATSIZE];
03064 isc_result_t result;
03065
03066 INSIST(!DLVTRIED(val));
03067
03068 val->attributes |= VALATTR_DLVTRIED;
03069
03070 dns_name_format(unsecure, namebuf, sizeof(namebuf));
03071 validator_log(val, ISC_LOG_DEBUG(3),
03072 "plain DNSSEC returns unsecure (%s): looking for DLV",
03073 namebuf);
03074
03075 if (dns_name_issubdomain(val->event->name, val->view->dlv)) {
03076 validator_log(val, ISC_LOG_WARNING, "must be secure failure, "
03077 " %s is under DLV (startfinddlvsep)", namebuf);
03078 return (DNS_R_MUSTBESECURE);
03079 }
03080
03081 val->dlvlabels = dns_name_countlabels(unsecure) - 1;
03082 result = finddlvsep(val, ISC_FALSE);
03083 if (result == ISC_R_NOTFOUND) {
03084 validator_log(val, ISC_LOG_DEBUG(3), "DLV not found");
03085 markanswer(val, "startfinddlvsep (1)");
03086 return (ISC_R_SUCCESS);
03087 }
03088 if (result == DNS_R_NTACOVERED) {
03089 validator_log(val, ISC_LOG_DEBUG(3), "DLV covered by NTA");
03090 validator_done(val, ISC_R_SUCCESS);
03091 return (ISC_R_SUCCESS);
03092 }
03093 if (result != ISC_R_SUCCESS) {
03094 validator_log(val, ISC_LOG_DEBUG(3), "DLV lookup: %s",
03095 dns_result_totext(result));
03096 return (result);
03097 }
03098 dns_name_format(dns_fixedname_name(&val->dlvsep), namebuf,
03099 sizeof(namebuf));
03100 if (dlv_algorithm_supported(val)) {
03101 validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found", namebuf);
03102 dlv_validator_start(val);
03103 return (DNS_R_WAIT);
03104 }
03105 validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found with no supported "
03106 "algorithms", namebuf);
03107 markanswer(val, "startfinddlvsep (2)");
03108 validator_done(val, ISC_R_SUCCESS);
03109 return (ISC_R_SUCCESS);
03110 }
03111
03112
03113
03114
03115
03116
03117
03118
03119
03120
03121 static isc_result_t
03122 finddlvsep(dns_validator_t *val, isc_boolean_t resume) {
03123 char namebuf[DNS_NAME_FORMATSIZE];
03124 dns_fixedname_t dlvfixed;
03125 dns_name_t *dlvname;
03126 dns_name_t *dlvsep;
03127 dns_name_t noroot;
03128 isc_result_t result;
03129 unsigned int labels;
03130
03131 INSIST(val->view->dlv != NULL);
03132
03133 if (!resume) {
03134 if (dns_name_issubdomain(val->event->name, val->view->dlv)) {
03135 dns_name_format(val->event->name, namebuf,
03136 sizeof(namebuf));
03137 validator_log(val, ISC_LOG_WARNING,
03138 "must be secure failure, "
03139 "%s is under DLV (finddlvsep)", namebuf);
03140 return (DNS_R_MUSTBESECURE);
03141 }
03142
03143 dns_fixedname_init(&val->dlvsep);
03144 dlvsep = dns_fixedname_name(&val->dlvsep);
03145 dns_name_copy(val->event->name, dlvsep, NULL);
03146
03147
03148
03149
03150 if (val->event->type == dns_rdatatype_ds) {
03151 labels = dns_name_countlabels(dlvsep);
03152 if (labels == 0)
03153 return (ISC_R_NOTFOUND);
03154 dns_name_getlabelsequence(dlvsep, 1, labels - 1,
03155 dlvsep);
03156 }
03157 } else {
03158 dlvsep = dns_fixedname_name(&val->dlvsep);
03159 labels = dns_name_countlabels(dlvsep);
03160 dns_name_getlabelsequence(dlvsep, 1, labels - 1, dlvsep);
03161 }
03162 dns_name_init(&noroot, NULL);
03163 dns_fixedname_init(&dlvfixed);
03164 dlvname = dns_fixedname_name(&dlvfixed);
03165 labels = dns_name_countlabels(dlvsep);
03166 if (labels == 0)
03167 return (ISC_R_NOTFOUND);
03168 dns_name_getlabelsequence(dlvsep, 0, labels - 1, &noroot);
03169 result = dns_name_concatenate(&noroot, val->view->dlv, dlvname, NULL);
03170 while (result == ISC_R_NOSPACE) {
03171 labels = dns_name_countlabels(dlvsep);
03172 dns_name_getlabelsequence(dlvsep, 1, labels - 1, dlvsep);
03173 dns_name_getlabelsequence(dlvsep, 0, labels - 2, &noroot);
03174 result = dns_name_concatenate(&noroot, val->view->dlv,
03175 dlvname, NULL);
03176 }
03177 if (result != ISC_R_SUCCESS) {
03178 validator_log(val, ISC_LOG_DEBUG(2), "DLV concatenate failed");
03179 return (DNS_R_NOVALIDSIG);
03180 }
03181
03182 if (((val->options & DNS_VALIDATOR_NONTA) == 0) &&
03183 dns_view_ntacovers(val->view, val->start, dlvname, val->view->dlv))
03184 return (DNS_R_NTACOVERED);
03185
03186 while (dns_name_countlabels(dlvname) >=
03187 dns_name_countlabels(val->view->dlv) + val->dlvlabels) {
03188 dns_name_format(dlvname, namebuf, sizeof(namebuf));
03189 validator_log(val, ISC_LOG_DEBUG(3), "looking for DLV %s",
03190 namebuf);
03191 result = view_find(val, dlvname, dns_rdatatype_dlv);
03192 if (result == ISC_R_SUCCESS) {
03193 if (DNS_TRUST_PENDING(val->frdataset.trust) &&
03194 dns_rdataset_isassociated(&val->fsigrdataset))
03195 {
03196 dns_fixedname_init(&val->fname);
03197 dns_name_copy(dlvname,
03198 dns_fixedname_name(&val->fname),
03199 NULL);
03200 result = create_validator(val,
03201 dns_fixedname_name(&val->fname),
03202 dns_rdatatype_dlv,
03203 &val->frdataset,
03204 &val->fsigrdataset,
03205 dlvvalidated,
03206 "finddlvsep");
03207 if (result != ISC_R_SUCCESS)
03208 return (result);
03209 return (DNS_R_WAIT);
03210 }
03211 if (val->frdataset.trust < dns_trust_secure) {
03212 validator_log(val, ISC_LOG_DEBUG(3),
03213 "DLV not validated");
03214 return (DNS_R_NOVALIDSIG);
03215 }
03216 val->havedlvsep = ISC_TRUE;
03217 dns_rdataset_clone(&val->frdataset, &val->dlv);
03218 return (ISC_R_SUCCESS);
03219 }
03220 if (result == ISC_R_NOTFOUND) {
03221 result = create_fetch(val, dlvname, dns_rdatatype_dlv,
03222 dlvfetched, "finddlvsep");
03223 if (result != ISC_R_SUCCESS)
03224 return (result);
03225 return (DNS_R_WAIT);
03226 }
03227 if (result != DNS_R_NXRRSET &&
03228 result != DNS_R_NXDOMAIN &&
03229 result != DNS_R_EMPTYNAME &&
03230 result != DNS_R_NCACHENXRRSET &&
03231 result != DNS_R_NCACHENXDOMAIN)
03232 return (result);
03233
03234
03235
03236 labels = dns_name_countlabels(dlvsep);
03237 if (labels == 0)
03238 break;
03239 dns_name_getlabelsequence(dlvsep, 1, labels - 1, dlvsep);
03240 labels = dns_name_countlabels(dlvname);
03241 dns_name_getlabelsequence(dlvname, 1, labels - 1, dlvname);
03242 }
03243 return (ISC_R_NOTFOUND);
03244 }
03245
03246
03247
03248
03249
03250
03251
03252
03253
03254
03255
03256
03257
03258
03259
03260
03261
03262
03263
03264
03265
03266 static isc_result_t
03267 proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
03268 {
03269 isc_result_t result;
03270 dns_fixedname_t fixedsecroot;
03271 dns_name_t *secroot;
03272 dns_name_t *tname;
03273 char namebuf[DNS_NAME_FORMATSIZE];
03274 dns_name_t *found;
03275 dns_fixedname_t fixedfound;
03276
03277 dns_fixedname_init(&fixedsecroot);
03278 secroot = dns_fixedname_name(&fixedsecroot);
03279 dns_fixedname_init(&fixedfound);
03280 found = dns_fixedname_name(&fixedfound);
03281 if (val->havedlvsep)
03282 dns_name_copy(dns_fixedname_name(&val->dlvsep), secroot, NULL);
03283 else {
03284 unsigned int labels;
03285 dns_name_copy(val->event->name, secroot, NULL);
03286
03287
03288
03289
03290
03291 labels = dns_name_countlabels(secroot);
03292 if (val->event->type == dns_rdatatype_ds && labels > 1U)
03293 dns_name_getlabelsequence(secroot, 1, labels - 1,
03294 secroot);
03295 result = dns_keytable_finddeepestmatch(val->keytable,
03296 secroot, secroot);
03297 if (result == ISC_R_NOTFOUND) {
03298 if (val->mustbesecure) {
03299 validator_log(val, ISC_LOG_WARNING,
03300 "must be secure failure, "
03301 "not beneath secure root");
03302 result = DNS_R_MUSTBESECURE;
03303 goto out;
03304 } else
03305 validator_log(val, ISC_LOG_DEBUG(3),
03306 "not beneath secure root");
03307 if (val->view->dlv == NULL || DLVTRIED(val)) {
03308 markanswer(val, "proveunsecure (1)");
03309 return (ISC_R_SUCCESS);
03310 }
03311 return (startfinddlvsep(val, dns_rootname));
03312 } else if (result != ISC_R_SUCCESS)
03313 return (result);
03314 }
03315
03316 if (!resume) {
03317
03318
03319
03320 val->labels = dns_name_countlabels(secroot) + 1;
03321 } else {
03322 validator_log(val, ISC_LOG_DEBUG(3), "resuming proveunsecure");
03323
03324
03325
03326
03327
03328
03329 if (have_ds && val->frdataset.trust >= dns_trust_secure &&
03330 !check_ds(val, dns_fixedname_name(&val->fname),
03331 &val->frdataset)) {
03332 dns_name_format(dns_fixedname_name(&val->fname),
03333 namebuf, sizeof(namebuf));
03334 if ((val->view->dlv == NULL || DLVTRIED(val)) &&
03335 val->mustbesecure) {
03336 validator_log(val, ISC_LOG_WARNING,
03337 "must be secure failure at '%s', "
03338 "can't fall back to DLV",
03339 namebuf);
03340 result = DNS_R_MUSTBESECURE;
03341 goto out;
03342 }
03343 validator_log(val, ISC_LOG_DEBUG(3),
03344 "no supported algorithm/digest (%s/DS)",
03345 namebuf);
03346 if (val->view->dlv == NULL || DLVTRIED(val)) {
03347 markanswer(val, "proveunsecure (2)");
03348 result = ISC_R_SUCCESS;
03349 goto out;
03350 }
03351 return(startfinddlvsep(val,
03352 dns_fixedname_name(&val->fname)));
03353 }
03354 val->labels++;
03355 }
03356
03357 for (;
03358 val->labels <= dns_name_countlabels(val->event->name);
03359 val->labels++)
03360 {
03361
03362 dns_fixedname_init(&val->fname);
03363 tname = dns_fixedname_name(&val->fname);
03364 if (val->labels == dns_name_countlabels(val->event->name))
03365 dns_name_copy(val->event->name, tname, NULL);
03366 else
03367 dns_name_split(val->event->name, val->labels,
03368 NULL, tname);
03369
03370 dns_name_format(tname, namebuf, sizeof(namebuf));
03371 validator_log(val, ISC_LOG_DEBUG(3),
03372 "checking existence of DS at '%s'",
03373 namebuf);
03374
03375 result = view_find(val, tname, dns_rdatatype_ds);
03376 if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) {
03377
03378
03379
03380
03381
03382
03383
03384
03385 if (DNS_TRUST_PENDING(val->frdataset.trust) ||
03386 DNS_TRUST_ANSWER(val->frdataset.trust)) {
03387 result = create_validator(val, tname,
03388 dns_rdatatype_ds,
03389 &val->frdataset,
03390 NULL, dsvalidated,
03391 "proveunsecure");
03392 if (result != ISC_R_SUCCESS)
03393 goto out;
03394 return (DNS_R_WAIT);
03395 }
03396
03397
03398
03399
03400
03401 if (result == DNS_R_NXRRSET &&
03402 !dns_rdataset_isassociated(&val->frdataset) &&
03403 dns_view_findzonecut2(val->view, tname, found,
03404 0, 0, ISC_FALSE, ISC_FALSE,
03405 NULL, NULL) == ISC_R_SUCCESS &&
03406 dns_name_equal(tname, found)) {
03407 if (val->mustbesecure) {
03408 validator_log(val, ISC_LOG_WARNING,
03409 "must be secure failure, "
03410 "no DS at zone cut");
03411 return (DNS_R_MUSTBESECURE);
03412 }
03413 if (val->view->dlv == NULL || DLVTRIED(val)) {
03414 markanswer(val, "proveunsecure (3)");
03415 return (ISC_R_SUCCESS);
03416 }
03417 return (startfinddlvsep(val, tname));
03418 }
03419 if (val->frdataset.trust < dns_trust_secure) {
03420
03421
03422
03423
03424
03425
03426 validator_log(val, ISC_LOG_WARNING,
03427 "can't validate existing "
03428 "negative responses (no DS)");
03429 result = DNS_R_NOVALIDSIG;
03430 goto out;
03431 }
03432 if (isdelegation(tname, &val->frdataset, result)) {
03433 if (val->mustbesecure) {
03434 validator_log(val, ISC_LOG_WARNING,
03435 "must be secure failure, "
03436 "%s is a delegation",
03437 namebuf);
03438 return (DNS_R_MUSTBESECURE);
03439 }
03440 if (val->view->dlv == NULL || DLVTRIED(val)) {
03441 markanswer(val, "proveunsecure (4)");
03442 return (ISC_R_SUCCESS);
03443 }
03444 return (startfinddlvsep(val, tname));
03445 }
03446 continue;
03447 } else if (result == DNS_R_CNAME) {
03448 if (DNS_TRUST_PENDING(val->frdataset.trust) ||
03449 DNS_TRUST_ANSWER(val->frdataset.trust)) {
03450 result = create_validator(val, tname,
03451 dns_rdatatype_cname,
03452 &val->frdataset,
03453 NULL, cnamevalidated,
03454 "proveunsecure "
03455 "(cname)");
03456 if (result != ISC_R_SUCCESS)
03457 goto out;
03458 return (DNS_R_WAIT);
03459 }
03460 continue;
03461 } else if (result == ISC_R_SUCCESS) {
03462
03463
03464
03465
03466 if (val->frdataset.trust >= dns_trust_secure) {
03467 if (!check_ds(val, tname, &val->frdataset)) {
03468 validator_log(val, ISC_LOG_DEBUG(3),
03469 "no supported algorithm/"
03470 "digest (%s/DS)", namebuf);
03471 if (val->mustbesecure) {
03472 validator_log(val,
03473 ISC_LOG_WARNING,
03474 "must be secure failure, "
03475 "no supported algorithm/"
03476 "digest (%s/DS)",
03477 namebuf);
03478 result = DNS_R_MUSTBESECURE;
03479 goto out;
03480 }
03481 if (val->view->dlv == NULL ||
03482 DLVTRIED(val)) {
03483 markanswer(val,
03484 "proveunsecure (5)");
03485 result = ISC_R_SUCCESS;
03486 goto out;
03487 }
03488 return(startfinddlvsep(val, tname));
03489 }
03490 continue;
03491 }
03492 else if (!dns_rdataset_isassociated(&val->fsigrdataset))
03493 {
03494 validator_log(val, ISC_LOG_DEBUG(3),
03495 "DS is unsigned");
03496 result = DNS_R_NOVALIDSIG;
03497 goto out;
03498 }
03499
03500
03501
03502 result = create_validator(val, tname, dns_rdatatype_ds,
03503 &val->frdataset,
03504 &val->fsigrdataset,
03505 dsvalidated,
03506 "proveunsecure");
03507 if (result != ISC_R_SUCCESS)
03508 goto out;
03509 return (DNS_R_WAIT);
03510 } else if (result == DNS_R_NXDOMAIN ||
03511 result == DNS_R_NCACHENXDOMAIN) {
03512
03513
03514
03515
03516 if (!dns_rdataset_isassociated(&val->frdataset)) {
03517
03518
03519
03520
03521 result = DNS_R_NOVALIDNSEC;
03522 goto out;
03523 } else if (DNS_TRUST_PENDING(val->frdataset.trust) ||
03524 DNS_TRUST_ANSWER(val->frdataset.trust)) {
03525
03526
03527
03528
03529 result = create_validator(val, tname,
03530 dns_rdatatype_ds,
03531 &val->frdataset,
03532 NULL, dsvalidated,
03533 "proveunsecure");
03534 if (result != ISC_R_SUCCESS)
03535 goto out;
03536 return (DNS_R_WAIT);
03537 } else if (val->frdataset.trust < dns_trust_secure) {
03538
03539
03540
03541
03542
03543
03544 validator_log(val, ISC_LOG_WARNING,
03545 "can't validate existing "
03546 "negative responses "
03547 "(not a zone cut)");
03548 result = DNS_R_NOVALIDSIG;
03549 goto out;
03550 }
03551 continue;
03552 } else if (result == ISC_R_NOTFOUND) {
03553
03554
03555
03556 result = create_fetch(val, tname, dns_rdatatype_ds,
03557 dsfetched2, "proveunsecure");
03558 if (result != ISC_R_SUCCESS)
03559 goto out;
03560 return (DNS_R_WAIT);
03561 } else if (result == DNS_R_BROKENCHAIN)
03562 return (result);
03563 }
03564
03565
03566 validator_log(val, ISC_LOG_DEBUG(3), "insecurity proof failed");
03567 return (DNS_R_NOTINSECURE);
03568
03569 out:
03570 if (dns_rdataset_isassociated(&val->frdataset))
03571 dns_rdataset_disassociate(&val->frdataset);
03572 if (dns_rdataset_isassociated(&val->fsigrdataset))
03573 dns_rdataset_disassociate(&val->fsigrdataset);
03574 return (result);
03575 }
03576
03577
03578
03579
03580 static void
03581 dlv_validator_start(dns_validator_t *val) {
03582 isc_event_t *event;
03583
03584 validator_log(val, ISC_LOG_DEBUG(3), "dlv_validator_start");
03585
03586
03587
03588
03589 val->attributes &= VALATTR_DLVTRIED;
03590 val->options &= ~DNS_VALIDATOR_DLV;
03591
03592 event = (isc_event_t *)val->event;
03593 isc_task_send(val->task, &event);
03594 }
03595
03596
03597
03598
03599
03600
03601
03602
03603
03604
03605
03606
03607
03608 static void
03609 validator_start(isc_task_t *task, isc_event_t *event) {
03610 dns_validator_t *val;
03611 dns_validatorevent_t *vevent;
03612 isc_boolean_t want_destroy = ISC_FALSE;
03613 isc_result_t result = ISC_R_FAILURE;
03614
03615 UNUSED(task);
03616 REQUIRE(event->ev_type == DNS_EVENT_VALIDATORSTART);
03617 vevent = (dns_validatorevent_t *)event;
03618 val = vevent->validator;
03619
03620
03621 if (val->event == NULL)
03622 return;
03623
03624 if (DLVTRIED(val))
03625 validator_log(val, ISC_LOG_DEBUG(3), "restarting using DLV");
03626 else
03627 validator_log(val, ISC_LOG_DEBUG(3), "starting");
03628
03629 LOCK(&val->lock);
03630
03631 if ((val->options & DNS_VALIDATOR_DLV) != 0 &&
03632 val->event->rdataset != NULL) {
03633 validator_log(val, ISC_LOG_DEBUG(3), "looking for DLV");
03634 result = startfinddlvsep(val, dns_rootname);
03635 } else if (val->event->rdataset != NULL &&
03636 val->event->sigrdataset != NULL) {
03637 isc_result_t saved_result;
03638
03639
03640
03641
03642
03643 validator_log(val, ISC_LOG_DEBUG(3),
03644 "attempting positive response validation");
03645
03646 INSIST(dns_rdataset_isassociated(val->event->rdataset));
03647 INSIST(dns_rdataset_isassociated(val->event->sigrdataset));
03648 result = start_positive_validation(val);
03649 if (result == DNS_R_NOVALIDSIG &&
03650 (val->attributes & VALATTR_TRIEDVERIFY) == 0)
03651 {
03652 saved_result = result;
03653 validator_log(val, ISC_LOG_DEBUG(3),
03654 "falling back to insecurity proof");
03655 val->attributes |= VALATTR_INSECURITY;
03656 result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
03657 if (result == DNS_R_NOTINSECURE)
03658 result = saved_result;
03659 }
03660 } else if (val->event->rdataset != NULL &&
03661 val->event->rdataset->type != 0) {
03662
03663
03664
03665
03666 INSIST(dns_rdataset_isassociated(val->event->rdataset));
03667 validator_log(val, ISC_LOG_DEBUG(3),
03668 "attempting insecurity proof");
03669
03670 val->attributes |= VALATTR_INSECURITY;
03671 result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
03672 if (result == DNS_R_NOTINSECURE)
03673 validator_log(val, ISC_LOG_INFO,
03674 "got insecure response; "
03675 "parent indicates it should be secure");
03676 } else if (val->event->rdataset == NULL &&
03677 val->event->sigrdataset == NULL)
03678 {
03679
03680
03681
03682 validator_log(val, ISC_LOG_DEBUG(3),
03683 "attempting negative response validation");
03684
03685 if (val->event->message->rcode == dns_rcode_nxdomain) {
03686 val->attributes |= VALATTR_NEEDNOQNAME;
03687 val->attributes |= VALATTR_NEEDNOWILDCARD;
03688 } else
03689 val->attributes |= VALATTR_NEEDNODATA;
03690 result = nsecvalidate(val, ISC_FALSE);
03691 } else if (val->event->rdataset != NULL &&
03692 NEGATIVE(val->event->rdataset))
03693 {
03694
03695
03696
03697 validator_log(val, ISC_LOG_DEBUG(3),
03698 "attempting negative response validation");
03699
03700 if (val->event->rdataset->covers == dns_rdatatype_any) {
03701 val->attributes |= VALATTR_NEEDNOQNAME;
03702 val->attributes |= VALATTR_NEEDNOWILDCARD;
03703 } else
03704 val->attributes |= VALATTR_NEEDNODATA;
03705 result = nsecvalidate(val, ISC_FALSE);
03706 } else {
03707
03708
03709
03710 INSIST(0);
03711 }
03712
03713 if (result != DNS_R_WAIT) {
03714 want_destroy = exit_check(val);
03715 validator_done(val, result);
03716 }
03717
03718 UNLOCK(&val->lock);
03719 if (want_destroy)
03720 destroy(val);
03721 }
03722
03723 isc_result_t
03724 dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
03725 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
03726 dns_message_t *message, unsigned int options,
03727 isc_task_t *task, isc_taskaction_t action, void *arg,
03728 dns_validator_t **validatorp)
03729 {
03730 isc_result_t result = ISC_R_FAILURE;
03731 dns_validator_t *val;
03732 isc_task_t *tclone = NULL;
03733 dns_validatorevent_t *event;
03734
03735 REQUIRE(name != NULL);
03736 REQUIRE(rdataset != NULL ||
03737 (rdataset == NULL && sigrdataset == NULL && message != NULL));
03738 REQUIRE(validatorp != NULL && *validatorp == NULL);
03739
03740 val = isc_mem_get(view->mctx, sizeof(*val));
03741 if (val == NULL)
03742 return (ISC_R_NOMEMORY);
03743 val->view = NULL;
03744 dns_view_weakattach(view, &val->view);
03745
03746 event = (dns_validatorevent_t *)
03747 isc_event_allocate(view->mctx, task,
03748 DNS_EVENT_VALIDATORSTART,
03749 validator_start, NULL,
03750 sizeof(dns_validatorevent_t));
03751 if (event == NULL) {
03752 result = ISC_R_NOMEMORY;
03753 goto cleanup_val;
03754 }
03755 isc_task_attach(task, &tclone);
03756 event->validator = val;
03757 event->result = ISC_R_FAILURE;
03758 event->name = name;
03759 event->type = type;
03760 event->rdataset = rdataset;
03761 event->sigrdataset = sigrdataset;
03762 event->message = message;
03763 memset(event->proofs, 0, sizeof(event->proofs));
03764 event->optout = ISC_FALSE;
03765 event->secure = ISC_FALSE;
03766 result = isc_mutex_init(&val->lock);
03767 if (result != ISC_R_SUCCESS)
03768 goto cleanup_event;
03769 val->event = event;
03770 val->options = options;
03771 val->attributes = 0;
03772 val->fetch = NULL;
03773 val->subvalidator = NULL;
03774 val->parent = NULL;
03775
03776 val->keytable = NULL;
03777 result = dns_view_getsecroots(val->view, &val->keytable);
03778 if (result != ISC_R_SUCCESS)
03779 goto cleanup_mutex;
03780 val->keynode = NULL;
03781 val->key = NULL;
03782 val->siginfo = NULL;
03783 val->task = task;
03784 val->action = action;
03785 val->arg = arg;
03786 val->labels = 0;
03787 val->currentset = NULL;
03788 val->keyset = NULL;
03789 val->dsset = NULL;
03790 dns_rdataset_init(&val->dlv);
03791 val->seensig = ISC_FALSE;
03792 val->havedlvsep = ISC_FALSE;
03793 val->depth = 0;
03794 val->authcount = 0;
03795 val->authfail = 0;
03796 val->mustbesecure = dns_resolver_getmustbesecure(view->resolver, name);
03797 dns_rdataset_init(&val->frdataset);
03798 dns_rdataset_init(&val->fsigrdataset);
03799 dns_fixedname_init(&val->wild);
03800 dns_fixedname_init(&val->nearest);
03801 dns_fixedname_init(&val->closest);
03802 isc_stdtime_get(&val->start);
03803 ISC_LINK_INIT(val, link);
03804 val->magic = VALIDATOR_MAGIC;
03805
03806 if ((options & DNS_VALIDATOR_DEFER) == 0)
03807 isc_task_send(task, ISC_EVENT_PTR(&event));
03808
03809 *validatorp = val;
03810
03811 return (ISC_R_SUCCESS);
03812
03813 cleanup_mutex:
03814 DESTROYLOCK(&val->lock);
03815
03816 cleanup_event:
03817 isc_task_detach(&tclone);
03818 isc_event_free(ISC_EVENT_PTR(&event));
03819
03820 cleanup_val:
03821 dns_view_weakdetach(&val->view);
03822 isc_mem_put(view->mctx, val, sizeof(*val));
03823
03824 return (result);
03825 }
03826
03827 void
03828 dns_validator_send(dns_validator_t *validator) {
03829 isc_event_t *event;
03830 REQUIRE(VALID_VALIDATOR(validator));
03831
03832 LOCK(&validator->lock);
03833
03834 INSIST((validator->options & DNS_VALIDATOR_DEFER) != 0);
03835 event = (isc_event_t *)validator->event;
03836 validator->options &= ~DNS_VALIDATOR_DEFER;
03837 UNLOCK(&validator->lock);
03838
03839 isc_task_send(validator->task, ISC_EVENT_PTR(&event));
03840 }
03841
03842 void
03843 dns_validator_cancel(dns_validator_t *validator) {
03844 dns_fetch_t *fetch = NULL;
03845
03846 REQUIRE(VALID_VALIDATOR(validator));
03847
03848 LOCK(&validator->lock);
03849
03850 validator_log(validator, ISC_LOG_DEBUG(3), "dns_validator_cancel");
03851
03852 if ((validator->attributes & VALATTR_CANCELED) == 0) {
03853 validator->attributes |= VALATTR_CANCELED;
03854 if (validator->event != NULL) {
03855 fetch = validator->fetch;
03856 validator->fetch = NULL;
03857
03858 if (validator->subvalidator != NULL)
03859 dns_validator_cancel(validator->subvalidator);
03860 if ((validator->options & DNS_VALIDATOR_DEFER) != 0) {
03861 validator->options &= ~DNS_VALIDATOR_DEFER;
03862 validator_done(validator, ISC_R_CANCELED);
03863 }
03864 }
03865 }
03866 UNLOCK(&validator->lock);
03867
03868
03869 if (fetch != NULL) {
03870 dns_resolver_cancelfetch(fetch);
03871 dns_resolver_destroyfetch(&fetch);
03872 }
03873 }
03874
03875 static void
03876 destroy(dns_validator_t *val) {
03877 isc_mem_t *mctx;
03878
03879 REQUIRE(SHUTDOWN(val));
03880 REQUIRE(val->event == NULL);
03881 REQUIRE(val->fetch == NULL);
03882
03883 if (val->keynode != NULL)
03884 dns_keytable_detachkeynode(val->keytable, &val->keynode);
03885 else if (val->key != NULL)
03886 dst_key_free(&val->key);
03887 if (val->keytable != NULL)
03888 dns_keytable_detach(&val->keytable);
03889 if (val->subvalidator != NULL)
03890 dns_validator_destroy(&val->subvalidator);
03891 if (val->havedlvsep)
03892 dns_rdataset_disassociate(&val->dlv);
03893 if (dns_rdataset_isassociated(&val->frdataset))
03894 dns_rdataset_disassociate(&val->frdataset);
03895 if (dns_rdataset_isassociated(&val->fsigrdataset))
03896 dns_rdataset_disassociate(&val->fsigrdataset);
03897 mctx = val->view->mctx;
03898 if (val->siginfo != NULL)
03899 isc_mem_put(mctx, val->siginfo, sizeof(*val->siginfo));
03900 DESTROYLOCK(&val->lock);
03901 dns_view_weakdetach(&val->view);
03902 val->magic = 0;
03903 isc_mem_put(mctx, val, sizeof(*val));
03904 }
03905
03906 void
03907 dns_validator_destroy(dns_validator_t **validatorp) {
03908 dns_validator_t *val;
03909 isc_boolean_t want_destroy = ISC_FALSE;
03910
03911 REQUIRE(validatorp != NULL);
03912 val = *validatorp;
03913 REQUIRE(VALID_VALIDATOR(val));
03914
03915 LOCK(&val->lock);
03916
03917 val->attributes |= VALATTR_SHUTDOWN;
03918 validator_log(val, ISC_LOG_DEBUG(4), "dns_validator_destroy");
03919
03920 want_destroy = exit_check(val);
03921
03922 UNLOCK(&val->lock);
03923
03924 if (want_destroy)
03925 destroy(val);
03926
03927 *validatorp = NULL;
03928 }
03929
03930 static void
03931 validator_logv(dns_validator_t *val, isc_logcategory_t *category,
03932 isc_logmodule_t *module, int level, const char *fmt, va_list ap)
03933 {
03934 char msgbuf[2048];
03935 static const char spaces[] = " *";
03936 int depth = val->depth * 2;
03937
03938 vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
03939
03940 if ((unsigned int) depth >= sizeof spaces)
03941 depth = sizeof spaces - 1;
03942
03943 if (val->event != NULL && val->event->name != NULL) {
03944 char namebuf[DNS_NAME_FORMATSIZE];
03945 char typebuf[DNS_RDATATYPE_FORMATSIZE];
03946
03947 dns_name_format(val->event->name, namebuf, sizeof(namebuf));
03948 dns_rdatatype_format(val->event->type, typebuf,
03949 sizeof(typebuf));
03950 isc_log_write(dns_lctx, category, module, level,
03951 "%.*svalidating %s/%s: %s", depth, spaces,
03952 namebuf, typebuf, msgbuf);
03953 } else {
03954 isc_log_write(dns_lctx, category, module, level,
03955 "%.*svalidator @%p: %s", depth, spaces,
03956 val, msgbuf);
03957 }
03958 }
03959
03960 static void
03961 validator_log(void *val, int level, const char *fmt, ...) {
03962 va_list ap;
03963
03964 if (! isc_log_wouldlog(dns_lctx, level))
03965 return;
03966
03967 va_start(ap, fmt);
03968
03969 validator_logv(val, DNS_LOGCATEGORY_DNSSEC,
03970 DNS_LOGMODULE_VALIDATOR, level, fmt, ap);
03971 va_end(ap);
03972 }
03973
03974 static void
03975 validator_logcreate(dns_validator_t *val,
03976 dns_name_t *name, dns_rdatatype_t type,
03977 const char *caller, const char *operation)
03978 {
03979 char namestr[DNS_NAME_FORMATSIZE];
03980 char typestr[DNS_RDATATYPE_FORMATSIZE];
03981
03982 dns_name_format(name, namestr, sizeof(namestr));
03983 dns_rdatatype_format(type, typestr, sizeof(typestr));
03984 validator_log(val, ISC_LOG_DEBUG(9), "%s: creating %s for %s %s",
03985 caller, operation, namestr, typestr);
03986 }