Home | History | Annotate | Line # | Download | only in fuzz
      1 /*	$NetBSD: dns_message_checksig.c,v 1.3 2025/01/26 16:25:20 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      5  *
      6  * SPDX-License-Identifier: MPL-2.0
      7  *
      8  * This Source Code Form is subject to the terms of the Mozilla Public
      9  * License, v. 2.0. If a copy of the MPL was not distributed with this
     10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
     11  *
     12  * See the COPYRIGHT file distributed with this work for additional
     13  * information regarding copyright ownership.
     14  */
     15 
     16 #include <inttypes.h>
     17 #include <stdbool.h>
     18 #include <stdlib.h>
     19 #include <unistd.h>
     20 
     21 #include <isc/buffer.h>
     22 #include <isc/commandline.h>
     23 #include <isc/file.h>
     24 #include <isc/mem.h>
     25 #include <isc/result.h>
     26 #include <isc/string.h>
     27 #include <isc/tid.h>
     28 #include <isc/util.h>
     29 
     30 #include <dns/fixedname.h>
     31 #include <dns/message.h>
     32 #include <dns/name.h>
     33 #include <dns/rcode.h>
     34 #include <dns/tsig.h>
     35 #include <dns/view.h>
     36 #include <dns/zone.h>
     37 
     38 #include "fuzz.h"
     39 
     40 bool debug = false;
     41 
     42 static isc_mem_t *mctx = NULL;
     43 
     44 /*
     45  *	Packet dumps of validily signed request ./IN/SOA
     46  *	requests.
     47  *
     48  *	TSIG:
     49  *
     50  *	0x0000:  600b 0900 006a 1140 0000 0000 0000 0000
     51  *	0x0010:  0000 0000 0000 0001 0000 0000 0000 0000
     52  *	0x0020:  0000 0000 0000 0001 cc88 0035 006a 007d
     53  *	0x0030:  1dfa 0000 0001 0000 0000 0001 0000 0600
     54  *	0x0040:  0108 7473 6967 2d6b 6579 0000 fa00 ff00
     55  *	0x0050:  0000 0000 3d0b 686d 6163 2d73 6861 3235
     56  *	0x0060:  3600 0000 622a cce1 012c 0020 224d 5807
     57  *	0x0070:  648d 1400 9d8e fc1c d049 55e9 cc90 2187
     58  *	0x0080:  3b5f af5c 8899 dc27 c8df b34b 1dfa 0000
     59  *	0x0090:  0000
     60  *
     61  *	SIG(0):
     62  *
     63  *	0x0000:  6004 0e00 013f 1140 0000 0000 0000 0000
     64  *	0x0010:  0000 0000 0000 0001 0000 0000 0000 0000
     65  *	0x0020:  0000 0000 0000 0001 c0a7 0035 013f 0152
     66  *	0x0030:  0000 0000 0001 0000 0000 0001 0000 0600
     67  *	0x0040:  0100 0018 00ff 0000 0000 011b 0000 0800
     68  *	0x0050:  0000 0000 622a ce0d 622a cbb5 da71 0773
     69  *	0x0060:  6967 306b 6579 0068 988b 27bf 5c89 5270
     70  *	0x0070:  c5ba ea8b 2e10 0512 9b44 48d3 69de b7ec
     71  *	0x0080:  7c67 15f3 6bc7 b0dc 277b e8f1 6979 4c89
     72  *	0x0090:  149a 0203 30a1 c0b7 a711 ee8a 8d90 ebb9
     73  *	0x00a0:  9e33 dd65 33d5 5d1d 90db cf9c bb6a b346
     74  *	0x00b0:  568f a399 71d7 c877 616d 2fb7 0f86 963f
     75  *	0x00c0:  aa00 850d 180a 9f83 cd4b d115 c79f 64c9
     76  *	0x00d0:  ff05 e751 6810 28b3 2249 c4ba 2d8d 57ba
     77  *	0x00e0:  9aad f1fc b34e c237 9465 04fd fe4d 19c9
     78  *	0x00f0:  2368 ec8e 7097 eaea e067 2b9c 06eb c383
     79  *	0x0100:  e901 a11e 606b 4cce c12a 0e57 8c09 b7cb
     80  *	0x0110:  23bb ec05 b68b 1852 9288 b665 fe89 cf62
     81  *	0x0120:  0a41 5e5a acbe 6903 cbb7 e7b6 cab4 e4a2
     82  *	0x0130:  b98f 884f c09d 5b39 c695 c84c 9a92 f110
     83  *	0x0140:  ccc3 f2ee 313f a2a1 1cda 5aa2 faec d593
     84  *	0x0150:  4514 724a 868f 94b9 0547 4dc9 7b73 c85e
     85  *	0x0160:  544c 73d4 e892 f9
     86  */
     87 
     88 #define HMACSHA256 "\x0bhmac-sha256"
     89 
     90 static isc_stdtime_t fuzztime = 0x622acce1;
     91 static isc_loopmgr_t *loopmgr = NULL;
     92 static dns_view_t *view = NULL;
     93 static dns_tsigkey_t *tsigkey = NULL;
     94 static dns_tsigkeyring_t *ring = NULL;
     95 static dns_tsigkeyring_t *emptyring = NULL;
     96 static char *wd = NULL;
     97 static char template[] = "/tmp/dns-message-checksig-XXXXXX";
     98 
     99 static char f1[] = "Ksig0key.+008+55921.key";
    100 static char c1[] = "sig0key. IN KEY 512 3 8 "
    101 		   "AwEAAa22lgHi1vAbQvu5ETdTrm2H8rwga9tvyMa6LFiSDyevLvSv0Uo5 "
    102 		   "uvfrXnxaLdtBMts6e1Ly2piSH9JRbOGMNibOK4EXWhWAn8MII4SWgQAs "
    103 		   "bFwtiz4HyPn2wScrUQdo8DocKiQJBanesr7vDO8fdA6Rg1e0yAtSeNti "
    104 		   "e8avx46/HJa6CFs3CoE0sf6oOFSxM954AgCBTXOGNBt1Nt3Bhfqt2qyA "
    105 		   "TLFii5K1jLDTZDVkoiyDXL1M7wcTwKf9METgj1eQmH3GGlRM/OJ/j8xk "
    106 		   "ZiFGbL3cipWdiH48031jiV2hlc92mKn8Ya0d9AN6c44piza/JSFydZXw "
    107 		   "sY32nxzjDbs=\n";
    108 
    109 static char f2[] = "Ksig0key.+008+55921.private";
    110 static char c2[] = "Private-key-format: v1.3\n\
    111 Algorithm: 8 (RSASHA256)\n\
    112 Modulus: rbaWAeLW8BtC+7kRN1OubYfyvCBr22/IxrosWJIPJ68u9K/RSjm69+tefFot20Ey2zp7UvLamJIf0lFs4Yw2Js4rgRdaFYCfwwgjhJaBACxsXC2LPgfI+fbBJytRB2jwOhwqJAkFqd6yvu8M7x90DpGDV7TIC1J422J7xq/Hjr8clroIWzcKgTSx/qg4VLEz3ngCAIFNc4Y0G3U23cGF+q3arIBMsWKLkrWMsNNkNWSiLINcvUzvBxPAp/0wROCPV5CYfcYaVEz84n+PzGRmIUZsvdyKlZ2IfjzTfWOJXaGVz3aYqfxhrR30A3pzjimLNr8lIXJ1lfCxjfafHOMNuw==\n\
    113 PublicExponent: AQAB\n\
    114 PrivateExponent: GDfclFkR5ToFGH9rMTRMnP73Q5dzjLgkx4vyHcuzKtxcvAans4+hNj+NazckAy2E+mpzV2j95TJ4wZjSM2RvB5xLwBIc4Dg6oyAHL6Ikoae6gw64cHFOaYb808n8CyqWqfX+QWAz9sRSVZXnTuPViX3A+svR7ejVak9Bzr1NTDm0DFlrhaKVCYA++dKVZerfuNiXT/jQvrc4wMCa7WWsfLsFO8aTNkEhqUnmS9c5VYgr7MkCV4ENDBcISpQc9wElI0hl12QPaSj8iSdk9liYp+HTiOxOyp6BGGuecKAoQijMwrZy4qExdOxvowptll8+nZLtwGRn/un/xvIZY5OLAQ==\n\
    115 Prime1: ww3C6jwnrLQik/zxSgC0KuqgHq68cCjiRjwK2/euzs7NkMevFpXvV0cWO8x1/wKC1mszVLsUaKTvH6fzRsXfz5MPihzNzUYFwvobKVLserSxEwHNk+FKUU+q07Kf8WWnCqX5nX9QzVG1q4J8Q44N49I5S480jHLGYbyLZrEYMQE=\n\
    116 Prime2: 4/3Ozq/8vRgcO4bieFs4CbZR7C98HiTi65SiLBIKY09mDfCleZI0uurAYBluZJgHS5AC5cdyHFuJr3uKxvD+Mgdlru40U6cSCEdK7HAhyUGZUndWl28wyMEB6Kke1/owxVn0S4RKLPOgFI2668H6JObaqXf0wyY89RdVQP6VQrs=\n\
    117 Exponent1: Tbr9MyVX1j5PDVSev5P6OKQZvUB7PeM9ESo6VaCl3CqTxx+cic6ke86LcLcxSrewdkxwP1LydiVMWfwvOcP/RhRf+/Uwmp5OC35qNpSiQuAhNObiCw2b9T1fYU/s52FQKTEtgXNMOxZV5IxyguVoaaLMTG08TsAqiKZ/kyP99QE=\n\
    118 Exponent2: Q4qSNKrwLbixzHS2LL+hR0dK17RtiaSV0QKUVIf3qdoAusp6yxwkIOegnBeMm6JqLtl38kh2pq37iRAJWcxVEc8dMYiB2fJZpjgwmwDREYUsfcC611vqUN7UyO8pIwSMZDq045ZKPyzhVJV0NZmemEYHq0LNMO7oCheiewGwiDc=\n\
    119 Coefficient: T2u/J4NgyO+OqoLpXBIpTBzqrvDk8tb0feYgsp5d16hHvbXxNkMUR8cI07RdbI9HnEldtmhAnbQ6SvFiy2YYjpw/1Fz2WwdxRqLaDV7UlhrT+CqltvU9d/N/xThBNKDa23Wf5Vat+HRiLHSgzsY1PseVCWN+g4azuK2D8+DLeHE=\n\
    120 Created: 20220311073606\n\
    121 Publish: 20220311073606\n\
    122 Activate: 20220311073606\n";
    123 
    124 static char f3[] = "sig0key.db";
    125 static char c3[] = "sig0key. 0 IN SOA . . 0 0 0 0 0\n\
    126 sig0key. 0 IN NS .\n\
    127 sig0key. 0 IN KEY 512 3 8 AwEAAa22lgHi1vAbQvu5ETdTrm2H8rwga9tvyMa6LFiSDyevLvSv0Uo5 uvfrXnxaLdtBMts6e1Ly2piSH9JRbOGMNibOK4EXWhWAn8MII4SWgQAs bFwtiz4HyPn2wScrUQdo8DocKiQJBanesr7vDO8fdA6Rg1e0yAtSeNti e8avx46/HJa6CFs3CoE0sf6oOFSxM954AgCBTXOGNBt1Nt3Bhfqt2qyA TLFii5K1jLDTZDVkoiyDXL1M7wcTwKf9METgj1eQmH3GGlRM/OJ/j8xk ZiFGbL3cipWdiH48031jiV2hlc92mKn8Ya0d9AN6c44piza/JSFydZXw sY32nxzjDbs=\n";
    128 
    129 static bool destroy_dst = false;
    130 
    131 int
    132 LLVMFuzzerInitialize(int *argc ISC_ATTR_UNUSED, char ***argv ISC_ATTR_UNUSED) {
    133 	isc_result_t result;
    134 	dns_fixedname_t fixed;
    135 	dns_name_t *name = dns_fixedname_initname(&fixed);
    136 	unsigned char secret[16] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    137 				     0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    138 				     0xff, 0xff, 0xff, 0xff };
    139 	dns_zone_t *zone = NULL;
    140 	char pathbuf[PATH_MAX];
    141 	FILE *fd;
    142 
    143 	wd = mkdtemp(template);
    144 	if (wd == NULL) {
    145 		fprintf(stderr, "mkdtemp failed\n");
    146 		return 1;
    147 	}
    148 
    149 	snprintf(pathbuf, sizeof(pathbuf), "%s/%s", wd, f1);
    150 	fd = fopen(pathbuf, "w");
    151 	if (fd == NULL) {
    152 		fprintf(stderr, "fopen(%s) failed\n", pathbuf);
    153 		return 1;
    154 	}
    155 	fputs(c1, fd);
    156 	fclose(fd);
    157 
    158 	snprintf(pathbuf, sizeof(pathbuf), "%s/%s", wd, f2);
    159 	fd = fopen(pathbuf, "w");
    160 	if (fd == NULL) {
    161 		fprintf(stderr, "fopen(%s) failed\n", pathbuf);
    162 		return 1;
    163 	}
    164 	fputs(c2, fd);
    165 	fclose(fd);
    166 
    167 	snprintf(pathbuf, sizeof(pathbuf), "%s/%s", wd, f3);
    168 	fd = fopen(pathbuf, "w");
    169 	if (fd == NULL) {
    170 		fprintf(stderr, "fopen(%s) failed\n", pathbuf);
    171 		return 1;
    172 	}
    173 	fputs(c3, fd);
    174 	fclose(fd);
    175 
    176 	isc_mem_create(&mctx);
    177 
    178 	result = dst_lib_init(mctx, NULL);
    179 	if (result != ISC_R_SUCCESS) {
    180 		fprintf(stderr, "dst_lib_init failed: %s\n",
    181 			isc_result_totext(result));
    182 		return 1;
    183 	}
    184 	destroy_dst = true;
    185 
    186 	isc_loopmgr_create(mctx, 1, &loopmgr);
    187 
    188 	result = dns_view_create(mctx, loopmgr, NULL, dns_rdataclass_in, "view",
    189 				 &view);
    190 	if (result != ISC_R_SUCCESS) {
    191 		fprintf(stderr, "dns_view_create failed: %s\n",
    192 			isc_result_totext(result));
    193 		return 1;
    194 	}
    195 
    196 	dns_tsigkeyring_create(mctx, &ring);
    197 	dns_tsigkeyring_create(mctx, &emptyring);
    198 
    199 	result = dns_name_fromstring(name, "tsig-key", dns_rootname, 0, NULL);
    200 	if (result != ISC_R_SUCCESS) {
    201 		fprintf(stderr, "dns_name_fromstring failed: %s\n",
    202 			isc_result_totext(result));
    203 		return 1;
    204 	}
    205 
    206 	result = dns_tsigkey_create(name, DST_ALG_HMACSHA256, secret,
    207 				    sizeof(secret), mctx, &tsigkey);
    208 	if (result != ISC_R_SUCCESS) {
    209 		fprintf(stderr, "dns_tsigkey_create failed: %s\n",
    210 			isc_result_totext(result));
    211 		return 1;
    212 	}
    213 	result = dns_tsigkeyring_add(ring, tsigkey);
    214 	if (result != ISC_R_SUCCESS) {
    215 		fprintf(stderr, "dns_tsigkeyring_add failed: %s\n",
    216 			isc_result_totext(result));
    217 		return 1;
    218 	}
    219 
    220 	result = dns_name_fromstring(name, "sig0key", dns_rootname, 0, NULL);
    221 	if (result != ISC_R_SUCCESS) {
    222 		fprintf(stderr, "dns_name_fromstring failed: %s\n",
    223 			isc_result_totext(result));
    224 		return 1;
    225 	}
    226 
    227 	dns_zone_create(&zone, mctx, 0);
    228 
    229 	result = dns_zone_setorigin(zone, name);
    230 	if (result != ISC_R_SUCCESS) {
    231 		fprintf(stderr, "dns_zone_setorigin failed: %s\n",
    232 			isc_result_totext(result));
    233 		return 1;
    234 	}
    235 
    236 	dns_zone_setclass(zone, view->rdclass);
    237 	dns_zone_settype(zone, dns_zone_primary);
    238 
    239 	result = dns_zone_setkeydirectory(zone, wd);
    240 	if (result != ISC_R_SUCCESS) {
    241 		fprintf(stderr, "dns_zone_setkeydirectory failed: %s\n",
    242 			isc_result_totext(result));
    243 		return 1;
    244 	}
    245 
    246 	result = dns_zone_setfile(zone, pathbuf, dns_masterformat_text,
    247 				  &dns_master_style_default);
    248 	if (result != ISC_R_SUCCESS) {
    249 		fprintf(stderr, "dns_zone_setfile failed: %s\n",
    250 			isc_result_totext(result));
    251 		return 1;
    252 	}
    253 
    254 	result = dns_zone_load(zone, false);
    255 	if (result != ISC_R_SUCCESS) {
    256 		fprintf(stderr, "dns_zone_load failed: %s\n",
    257 			isc_result_totext(result));
    258 		return 1;
    259 	}
    260 
    261 	result = dns_view_addzone(view, zone);
    262 	if (result != ISC_R_SUCCESS) {
    263 		fprintf(stderr, "dns_view_addzone failed: %s\n",
    264 			isc_result_totext(result));
    265 		return 1;
    266 	}
    267 
    268 	dns_zone_setview(zone, view);
    269 	dns_view_freeze(view);
    270 
    271 	dns_zone_detach(&zone);
    272 
    273 	return 0;
    274 }
    275 
    276 static isc_result_t
    277 create_message(dns_message_t **messagep, const uint8_t *data, size_t size,
    278 	       bool addasig, bool addtsig) {
    279 	isc_result_t result;
    280 	dns_message_t *message = NULL;
    281 	isc_buffer_t b;
    282 	static unsigned char buf[65535];
    283 
    284 	isc_buffer_init(&b, buf, sizeof(buf));
    285 
    286 	/* Message ID */
    287 	isc_buffer_putuint16(&b, 0);
    288 
    289 	/* QR, Opcode, other flags = 0, rcode = 0 */
    290 	isc_buffer_putuint16(&b, (*data & 0x1f) << 11);
    291 	/* Counts */
    292 	isc_buffer_putuint16(&b, 1);
    293 	isc_buffer_putuint16(&b, 0);
    294 	isc_buffer_putuint16(&b, 0);
    295 	isc_buffer_putuint16(&b, addasig ? 1 : 0);
    296 
    297 	/* Question ./IN/SOA */
    298 	isc_buffer_putuint8(&b, 0);
    299 	isc_buffer_putuint16(&b, 6);
    300 	isc_buffer_putuint16(&b, 1);
    301 
    302 	if (addasig) {
    303 		/* Signature */
    304 		if (addtsig) {
    305 			const unsigned char keyname[] = "\x08tsig-key";
    306 			isc_buffer_putmem(&b, keyname, sizeof(keyname));
    307 			isc_buffer_putuint16(&b, dns_rdatatype_tsig);
    308 			isc_buffer_putuint16(&b, dns_rdataclass_any);
    309 		} else {
    310 			isc_buffer_putuint8(&b, 0); /* '.' */
    311 			isc_buffer_putuint16(&b, dns_rdatatype_sig);
    312 			isc_buffer_putuint16(&b, dns_rdataclass_in);
    313 		}
    314 		isc_buffer_putuint32(&b, 0); /* ttl */
    315 		data++;
    316 		size--;
    317 		if (size > isc_buffer_availablelength(&b) - 2) {
    318 			size = isc_buffer_availablelength(&b) - 2;
    319 		}
    320 		isc_buffer_putuint16(&b, size);
    321 		isc_buffer_putmem(&b, data, size);
    322 	}
    323 
    324 	dns_message_create(mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, &message);
    325 
    326 	result = dns_message_parse(message, &b, 0);
    327 	if (debug) {
    328 		fprintf(stderr, "dns_message_parse => %s\n",
    329 			isc_result_totext(result));
    330 	}
    331 	if (result != ISC_R_SUCCESS) {
    332 		dns_message_detach(&message);
    333 	} else {
    334 		if (debug) {
    335 			char text[200000];
    336 			isc_buffer_init(&b, text, sizeof(text));
    337 
    338 			result = dns_message_totext(
    339 				message, &dns_master_style_debug, 0, &b);
    340 			if (result == ISC_R_SUCCESS) {
    341 				fprintf(stderr, "%.*s", (int)b.used, text);
    342 			} else {
    343 				fprintf(stderr, "dns_message_totext => %s\n",
    344 					isc_result_totext(result));
    345 			}
    346 		}
    347 		*messagep = message;
    348 	}
    349 	return result;
    350 }
    351 
    352 int
    353 LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
    354 	isc_result_t result;
    355 	dns_message_t *message = NULL;
    356 	unsigned char query_tsig[23 + 32 + 6] = { 0 };
    357 	bool addasig = false;
    358 	bool addtime = false;
    359 	bool addtsig = false;
    360 	bool setquerytsig = false;
    361 	bool settsigkey = false;
    362 	bool subtime = false;
    363 	bool withring = false;
    364 	bool withview = false;
    365 
    366 	/*
    367 	 * The first 2 octets affect setup.
    368 	 * Octet 1 determines whether a signature is added and which type
    369 	 * (addasig, addtsig), whether time should be adjusted (addtime,
    370 	 * subtime), whether dns_message_setquerytsig and dns_message_settsigkey
    371 	 * have been called, whether there is a keyring available with the
    372 	 * TSIG key or a view is defined.
    373 	 *
    374 	 * The second octet defines if the message is a response and the
    375 	 * opcode.
    376 	 */
    377 	if (size > 65535 || size < 2) {
    378 		return 0;
    379 	}
    380 
    381 	addasig = (*data & 0x80) != 0;
    382 	addtime = (*data & 0x40) != 0;
    383 	addtsig = (*data & 0x20) != 0;
    384 	setquerytsig = (*data & 0x10) != 0;
    385 	settsigkey = (*data & 0x08) != 0;
    386 	subtime = (*data & 0x04) != 0;
    387 	withring = (*data & 0x02) != 0;
    388 	withview = (*data & 0x01) != 0;
    389 
    390 	data++;
    391 	size--;
    392 
    393 	if (debug) {
    394 		fprintf(stderr,
    395 			"addasig=%u addtime=%u addtsig=%u setquerytsig=%u "
    396 			"settsigkey=%u subtime=%u withring=%u\nwithview=%u\n",
    397 			addasig, addtime, addtsig, setquerytsig, settsigkey,
    398 			subtime, withring, withview);
    399 	}
    400 
    401 	result = create_message(&message, data, size, addasig, addtsig);
    402 	if (result != ISC_R_SUCCESS) {
    403 		return 0;
    404 	}
    405 
    406 	/*
    407 	 * Make time calculations consistent.
    408 	 */
    409 	message->fuzzing = 1;
    410 	message->fuzztime = fuzztime;
    411 	if (addtime) {
    412 		message->fuzztime += 1200;
    413 	}
    414 	if (subtime) {
    415 		message->fuzztime -= 1200;
    416 	}
    417 
    418 	if ((message->flags & DNS_MESSAGEFLAG_QR) != 0) {
    419 		if (setquerytsig) {
    420 			isc_buffer_t b;
    421 			unsigned char hmacname[] = HMACSHA256;
    422 			unsigned char hmacvalue[32] = {
    423 				0x22, 0x4d, 0x58, 0x07, 0x64, 0x8d, 0x14, 0x00,
    424 				0x9d, 0x8e, 0xfc, 0x1c, 0xd0, 0x49, 0x55, 0xe9,
    425 				0xcc, 0x90, 0x21, 0x87, 0x3b, 0x5f, 0xaf, 0x5c,
    426 				0x88, 0x99, 0xdc, 0x27, 0xc8, 0xdf, 0xb3, 0x4b
    427 			};
    428 
    429 			/*
    430 			 * Valid TSIG rdata for tsig-key over a plain
    431 			 * DNS QUERY for ./SOA/IN with no flags set.
    432 			 */
    433 			isc_buffer_init(&b, query_tsig, sizeof(query_tsig));
    434 			isc_buffer_putmem(&b, hmacname, sizeof(hmacname));
    435 			isc_buffer_putuint16(&b, 0);	      /* time high */
    436 			isc_buffer_putuint32(&b, 0x622abec0); /* time low */
    437 			isc_buffer_putuint16(&b, 300);	      /* Fudge */
    438 			isc_buffer_putuint16(&b, 32);	      /* Mac Length */
    439 			/* Mac */
    440 			isc_buffer_putmem(&b, hmacvalue, 32);
    441 			isc_buffer_putuint16(&b, 7674); /* Original Id */
    442 			isc_buffer_putuint16(&b, 0);	/* Error */
    443 			isc_buffer_putuint16(&b, 0);	/* Other len */
    444 
    445 			dns_message_setquerytsig(message, &b);
    446 		}
    447 	}
    448 
    449 	if (settsigkey) {
    450 		result = dns_message_settsigkey(message, tsigkey);
    451 		if (debug) {
    452 			fprintf(stderr, "dns_message_settsigkey => %s\n",
    453 				isc_result_totext(result));
    454 		}
    455 	}
    456 
    457 	dns_view_setkeyring(view, withring ? ring : emptyring);
    458 
    459 	result = dns_message_checksig(message, withview ? view : NULL);
    460 	if (debug) {
    461 		char textbuf[64];
    462 		isc_buffer_t b;
    463 
    464 		fprintf(stderr, "dns_message_checksig => %s\n",
    465 			isc_result_totext(result));
    466 		isc_buffer_init(&b, textbuf, sizeof(textbuf));
    467 		dns_tsigrcode_totext(message->tsigstatus, &b);
    468 		fprintf(stderr, "tsigstatus=%.*s\n", (int)b.used, textbuf);
    469 		isc_buffer_init(&b, textbuf, sizeof(textbuf));
    470 		dns_tsigrcode_totext(message->sig0status, &b);
    471 		fprintf(stderr, "sig0status=%.*s\n", (int)b.used, textbuf);
    472 	}
    473 	if (result != ISC_R_SUCCESS) {
    474 		goto cleanup;
    475 	}
    476 
    477 cleanup:
    478 	if (message != NULL) {
    479 		dns_message_detach(&message);
    480 	}
    481 
    482 	return 0;
    483 }
    484