lib/dns/validator.c
/*%
 * Attempts positive response validation of a normal RRset.
 *
 * Returns:
 * \li	ISC_R_SUCCESS	Validation completed successfully
 * \li	DNS_R_WAIT	Validation has started but is waiting
 *			for an event.
 * \li	Other return codes are possible and all indicate failure.
 */
%
Attempts positive response validation of a normal RRset.

\li  ISC_R_SUCCESS   Validation completed successfully
\li  DNS_R_WAIT      Validation has started but is waiting
for an event.
\li  Other return codes are possible and all indicate failure.
% Attempts positive response validation of a normal RRset . \ li ISC_R_SUCCESS Validation completed successfully \ li DNS_R_WAIT Validation has started but is waiting for an event . \ li Other return codes are possible and all indicate failure .
static isc_result_t
validate(dns_validator_t *val, isc_boolean_t resume) {
	isc_result_t result;
	dns_validatorevent_t *event;
	dns_rdata_t rdata = DNS_RDATA_INIT;
	event = val->event;
	if (resume) {
		result = ISC_R_SUCCESS;
		validator_log(val, ISC_LOG_DEBUG(3), "resuming validate");
	} else {
		result = dns_rdataset_first(event->sigrdataset);
	}
	for (;
	     result == ISC_R_SUCCESS;
	     result = dns_rdataset_next(event->sigrdataset))
	{
		dns_rdata_reset(&rdata);
		dns_rdataset_current(event->sigrdataset, &rdata);
		if (val->siginfo == NULL) {
			val->siginfo = isc_mem_get(val->view->mctx,
						   sizeof(*val->siginfo));
			if (val->siginfo == NULL)
				return (ISC_R_NOMEMORY);
		}
		result = dns_rdata_tostruct(&rdata, val->siginfo, NULL);
		if (result != ISC_R_SUCCESS)
			return (result);
		if (!dns_resolver_algorithm_supported(val->view->resolver,
						    event->name,
						    val->siginfo->algorithm)) {
			resume = ISC_FALSE;
			continue;
		}
		if (!resume) {
			result = get_key(val, val->siginfo);
			if (result == DNS_R_CONTINUE)
				continue; 
			if (result != ISC_R_SUCCESS)
				return (result);
		}
		if (val->key == NULL) {
			resume = ISC_FALSE;
			continue;
		}
		do {
			result = verify(val, val->key, &rdata,
					val->siginfo->keyid);
			if (result == ISC_R_SUCCESS)
				break;
			if (val->keynode != NULL) {
				dns_keynode_t *nextnode = NULL;
				result = dns_keytable_findnextkeynode(
							val->keytable,
							val->keynode,
							&nextnode);
				dns_keytable_detachkeynode(val->keytable,
							   &val->keynode);
				val->keynode = nextnode;
				if (result != ISC_R_SUCCESS) {
					val->key = NULL;
					break;
				}
				val->key = dns_keynode_key(val->keynode);
				if (val->key == NULL)
					break;
			} else {
				if (get_dst_key(val, val->siginfo, val->keyset)
				    != ISC_R_SUCCESS)
					break;
			}
		} while (1);
		if (result != ISC_R_SUCCESS)
			validator_log(val, ISC_LOG_DEBUG(3),
				      "failed to verify rdataset");
		else {
			isc_uint32_t ttl;
			isc_stdtime_t now;
			isc_stdtime_get(&now);
			ttl = ISC_MIN(event->rdataset->ttl,
				      ISC_MIN(val->siginfo->originalttl,
					      val->siginfo->timeexpire - now));
			event->rdataset->ttl = ttl;
			event->sigrdataset->ttl = ttl;
		}
		if (val->keynode != NULL)
			dns_keytable_detachkeynode(val->keytable,
						   &val->keynode);
		else {
			if (val->key != NULL)
				dst_key_free(&val->key);
			if (val->keyset != NULL) {
				dns_rdataset_disassociate(val->keyset);
				val->keyset = NULL;
			}
		}
		val->key = NULL;
		if (NEEDNOQNAME(val)) {
			if (val->event->message == NULL) {
				validator_log(val, ISC_LOG_DEBUG(3),
				      "no message available for noqname proof");
				return (DNS_R_NOVALIDSIG);
			}
			validator_log(val, ISC_LOG_DEBUG(3),
				      "looking for noqname proof");
			return (nsecvalidate(val, ISC_FALSE));
		} else if (result == ISC_R_SUCCESS) {
			marksecure(event);
			validator_log(val, ISC_LOG_DEBUG(3),
				      "marking as secure, "
				      "noqname proof not needed");
			return (result);
		} else {
			validator_log(val, ISC_LOG_DEBUG(3),
				      "verify failure: %s",
				      isc_result_totext(result));
			resume = ISC_FALSE;
		}
	}
	if (result != ISC_R_NOMORE) {
		validator_log(val, ISC_LOG_DEBUG(3),
			      "failed to iterate signatures: %s",
			      isc_result_totext(result));
		return (result);
	}
	validator_log(val, ISC_LOG_INFO, "no valid signature found");
	return (DNS_R_NOVALIDSIG);
}
static isc_result_t validate ( dns_validator_t * val , isc_boolean_t resume ) { isc_result_t result ; dns_validatorevent_t * event ; dns_rdata_t rdata = DNS_RDATA_INIT ; event = val -> event ; if ( resume ) { result = ISC_R_SUCCESS ; validator_log ( val , ISC_LOG_DEBUG ( 3 ) , " " ) ; } else { result = dns_rdataset_first ( event -> sigrdataset ) ; } for ( ; result == ISC_R_SUCCESS ; result = dns_rdataset_next ( event -> sigrdataset ) ) { dns_rdata_reset ( & rdata ) ; dns_rdataset_current ( event -> sigrdataset , & rdata ) ; if ( val -> siginfo == NULL ) { val -> siginfo = isc_mem_get ( val -> view -> mctx , sizeof ( * val -> siginfo ) ) ; if ( val -> siginfo == NULL ) return ( ISC_R_NOMEMORY ) ; } result = dns_rdata_tostruct ( & rdata , val -> siginfo , NULL ) ; if ( result != ISC_R_SUCCESS ) return ( result ) ; if ( ! dns_resolver_algorithm_supported ( val -> view -> resolver , event -> name , val -> siginfo -> algorithm ) ) { resume = ISC_FALSE ; continue ; } if ( ! resume ) { result = get_key ( val , val -> siginfo ) ; if ( result == DNS_R_CONTINUE ) continue ; if ( result != ISC_R_SUCCESS ) return ( result ) ; } if ( val -> key == NULL ) { resume = ISC_FALSE ; continue ; } do { result = verify ( val , val -> key , & rdata , val -> siginfo -> keyid ) ; if ( result == ISC_R_SUCCESS ) break ; if ( val -> keynode != NULL ) { dns_keynode_t * nextnode = NULL ; result = dns_keytable_findnextkeynode ( val -> keytable , val -> keynode , & nextnode ) ; dns_keytable_detachkeynode ( val -> keytable , & val -> keynode ) ; val -> keynode = nextnode ; if ( result != ISC_R_SUCCESS ) { val -> key = NULL ; break ; } val -> key = dns_keynode_key ( val -> keynode ) ; if ( val -> key == NULL ) break ; } else { if ( get_dst_key ( val , val -> siginfo , val -> keyset ) != ISC_R_SUCCESS ) break ; } } while ( 1 ) ; if ( result != ISC_R_SUCCESS ) validator_log ( val , ISC_LOG_DEBUG ( 3 ) , " " ) ; else { isc_uint32_t ttl ; isc_stdtime_t now ; isc_stdtime_get ( & now ) ; ttl = ISC_MIN ( event -> rdataset -> ttl , ISC_MIN ( val -> siginfo -> originalttl , val -> siginfo -> timeexpire - now ) ) ; event -> rdataset -> ttl = ttl ; event -> sigrdataset -> ttl = ttl ; } if ( val -> keynode != NULL ) dns_keytable_detachkeynode ( val -> keytable , & val -> keynode ) ; else { if ( val -> key != NULL ) dst_key_free ( & val -> key ) ; if ( val -> keyset != NULL ) { dns_rdataset_disassociate ( val -> keyset ) ; val -> keyset = NULL ; } } val -> key = NULL ; if ( NEEDNOQNAME ( val ) ) { if ( val -> event -> message == NULL ) { validator_log ( val , ISC_LOG_DEBUG ( 3 ) , " " ) ; return ( DNS_R_NOVALIDSIG ) ; } validator_log ( val , ISC_LOG_DEBUG ( 3 ) , " " ) ; return ( nsecvalidate ( val , ISC_FALSE ) ) ; } else if ( result == ISC_R_SUCCESS ) { marksecure ( event ) ; validator_log ( val , ISC_LOG_DEBUG ( 3 ) , " " " " ) ; return ( result ) ; } else { validator_log ( val , ISC_LOG_DEBUG ( 3 ) , " " , isc_result_totext ( result ) ) ; resume = ISC_FALSE ; } } if ( result != ISC_R_NOMORE ) { validator_log ( val , ISC_LOG_DEBUG ( 3 ) , " " , isc_result_totext ( result ) ) ; return ( result ) ; } validator_log ( val , ISC_LOG_INFO , " " ) ; return ( DNS_R_NOVALIDSIG ) ; }
%
 Attempts positive response validation of a normal RRset.
% Attempts positive response validation of a normal RRset .
/*
	 * Caller must be holding the validator lock.
	 */ /*
		 * We already have a sigrdataset.
		 */ /*
		 * At this point we could check that the signature algorithm
		 * was known and "sufficiently good".
		 */ /* Try the next SIG RR. */ /*
		 * There isn't a secure DNSKEY for this signature so move
		 * onto the next RRSIG.
		 */