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