dns_message_signer(dns_message_t *msg, dns_name_t *signer) {
	isc_result_t result = ISC_R_SUCCESS;
	dns_rdata_t rdata = DNS_RDATA_INIT;

	REQUIRE(DNS_MESSAGE_VALID(msg));
	REQUIRE(signer != NULL);
	REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTPARSE);

	if (msg->tsig == NULL && msg->sig0 == NULL)
		return (ISC_R_NOTFOUND);

	if (msg->verify_attempted == 0)
		return (DNS_R_NOTVERIFIEDYET);

	if (!dns_name_hasbuffer(signer)) {
		isc_buffer_t *dynbuf = NULL;
		result = isc_buffer_allocate(msg->mctx, &dynbuf, 512);
		if (result != ISC_R_SUCCESS)
			return (result);
		dns_name_setbuffer(signer, dynbuf);
		dns_message_takebuffer(msg, &dynbuf);
	}

	if (msg->sig0 != NULL) {
		dns_rdata_sig_t sig;

		result = dns_rdataset_first(msg->sig0);
		INSIST(result == ISC_R_SUCCESS);
		dns_rdataset_current(msg->sig0, &rdata);

		result = dns_rdata_tostruct(&rdata, &sig, NULL);
		if (result != ISC_R_SUCCESS)
			return (result);

		if (msg->verified_sig && msg->sig0status == dns_rcode_noerror)
			result = ISC_R_SUCCESS;
		else
			result = DNS_R_SIGINVALID;
		dns_name_clone(&sig.signer, signer);
		dns_rdata_freestruct(&sig);
	} else {
		const dns_name_t *identity;
		dns_rdata_any_tsig_t tsig;

		result = dns_rdataset_first(msg->tsig);
		INSIST(result == ISC_R_SUCCESS);
		dns_rdataset_current(msg->tsig, &rdata);

		result = dns_rdata_tostruct(&rdata, &tsig, NULL);
		INSIST(result == ISC_R_SUCCESS);
		if (msg->verified_sig &&
		    msg->tsigstatus == dns_rcode_noerror &&
		    tsig.error == dns_rcode_noerror)
		{
			result = ISC_R_SUCCESS;
		} else if ((!msg->verified_sig) ||
			   (msg->tsigstatus != dns_rcode_noerror))
		{
			result = DNS_R_TSIGVERIFYFAILURE;
		} else {
			INSIST(tsig.error != dns_rcode_noerror);
			result = DNS_R_TSIGERRORSET;
		}
		dns_rdata_freestruct(&tsig);

		if (msg->tsigkey == NULL) {
			/*
			 * If msg->tsigstatus & tsig.error are both
			 * dns_rcode_noerror, the message must have been
			 * verified, which means msg->tsigkey will be
			 * non-NULL.
			 */
			INSIST(result != ISC_R_SUCCESS);
		} else {
			identity = dns_tsigkey_identity(msg->tsigkey);
			if (identity == NULL) {
				if (result == ISC_R_SUCCESS)
					result = DNS_R_NOIDENTITY;
				identity = &msg->tsigkey->name;
			}
			dns_name_clone(identity, signer);
		}
	}

	return (result);
}
Unknown