mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 06:25:31 +00:00
Merge branch 'ondrej-add-dns_message_checktsig-fuzzer' into 'main'
Add dns_message_checksig() fuzzer See merge request isc-projects/bind9!5923
This commit is contained in:
7
CHANGES
7
CHANGES
@@ -1,3 +1,10 @@
|
||||
5982. [func] Extend dig to allow requests to be signed using SIG(0)
|
||||
as well as providing a mechanism to specify the signing
|
||||
time. [GL !5923]
|
||||
|
||||
5981. [test] Add dns_message_checksig fuzzer to check messages
|
||||
signed using TSIG or SIG(0). [GL !5923]
|
||||
|
||||
5980. [func] The internal isc_entropy API provider has been
|
||||
changed from OpenSSL RAND_bytes() to uv_random()
|
||||
to use system provided entropy. [GL !6803]
|
||||
|
@@ -1522,8 +1522,31 @@ plus_option(char *option, bool is_batchfile, bool *need_clone,
|
||||
}
|
||||
break;
|
||||
case 'f': /* fail */
|
||||
FULLCHECK("fail");
|
||||
lookup->servfail_stops = state;
|
||||
switch (cmd[1]) {
|
||||
case 'a':
|
||||
FULLCHECK("fail");
|
||||
lookup->servfail_stops = state;
|
||||
break;
|
||||
case 'u':
|
||||
FULLCHECK("fuzztime");
|
||||
lookup->fuzzing = state;
|
||||
if (lookup->fuzzing) {
|
||||
if (value == NULL) {
|
||||
lookup->fuzztime = 0x622acce1;
|
||||
break;
|
||||
}
|
||||
result = parse_uint(&num, value, 0xffffffff,
|
||||
"fuzztime");
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
warn("Couldn't parse fuzztime");
|
||||
goto exit_or_usage;
|
||||
}
|
||||
lookup->fuzztime = num;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
goto invalid_option;
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
switch (cmd[1]) {
|
||||
|
@@ -132,12 +132,14 @@ Options
|
||||
|
||||
.. option:: -k keyfile
|
||||
|
||||
This option tells :iscman:`named` to sign queries using TSIG using a key read from the given file. Key
|
||||
files can be generated using :iscman:`tsig-keygen`. When using TSIG
|
||||
authentication with :program:`dig`, the name server that is queried needs to
|
||||
know the key and algorithm that is being used. In BIND, this is done
|
||||
by providing appropriate ``key`` and ``server`` statements in
|
||||
:iscman:`named.conf`.
|
||||
This option tells :program:`dig` to sign queries using TSIG or
|
||||
SIG(0) using a key read from the given file. Key files can be
|
||||
generated using :iscman:`tsig-keygen`. When using TSIG authentication
|
||||
with :program:`dig`, the name server that is queried needs to
|
||||
know the key and algorithm that is being used. In BIND, this is
|
||||
done by providing appropriate ``key`` and ``server`` statements
|
||||
in :iscman:`named.conf` for TSIG and by looking up the KEY record
|
||||
in zone data for SIG(0).
|
||||
|
||||
.. option:: -m
|
||||
|
||||
@@ -386,6 +388,14 @@ abbreviation is unambiguous; for example, :option:`+cd` is equivalent to
|
||||
to not try the next server, which is the reverse of normal stub
|
||||
resolver behavior.
|
||||
|
||||
.. option:: +fuzztime[=value], +nofuzztime
|
||||
|
||||
This option allows the signing time to be specified when generating
|
||||
signed messages. If a value is specified it is the seconds since
|
||||
00:00:00 January 1, 1970 UTC ignoring leap seconds. If no value
|
||||
is specified 1646972129 (Fri 11 Mar 2022 04:15:29 UTC) is used.
|
||||
The default is ``+nofuzztime`` and the current time is used.
|
||||
|
||||
.. option:: +header-only, +noheader-only
|
||||
|
||||
This option sends a query with a DNS header without a question section. The
|
||||
|
@@ -143,6 +143,7 @@ const dns_name_t *hmacname = NULL;
|
||||
unsigned int digestbits = 0;
|
||||
isc_buffer_t *namebuf = NULL;
|
||||
dns_tsigkey_t *tsigkey = NULL;
|
||||
dst_key_t *sig0key = NULL;
|
||||
bool validated = true;
|
||||
bool debugging = false;
|
||||
bool debugtiming = false;
|
||||
@@ -794,6 +795,8 @@ clone_lookup(dig_lookup_t *lookold, bool servers) {
|
||||
looknew->done_as_is = lookold->done_as_is;
|
||||
looknew->dscp = lookold->dscp;
|
||||
looknew->rrcomments = lookold->rrcomments;
|
||||
looknew->fuzzing = lookold->fuzzing;
|
||||
looknew->fuzztime = lookold->fuzztime;
|
||||
|
||||
if (lookold->ecs_addr != NULL) {
|
||||
size_t len = sizeof(isc_sockaddr_t);
|
||||
@@ -1141,6 +1144,10 @@ setup_file_key(void) {
|
||||
|
||||
debug("setup_file_key()");
|
||||
|
||||
if (sig0key != NULL) {
|
||||
dst_key_free(&sig0key);
|
||||
}
|
||||
|
||||
/* Try reading the key from a K* pair */
|
||||
result = dst_key_fromnamedfile(
|
||||
keyfile, NULL, DST_TYPE_PRIVATE | DST_TYPE_KEY, mctx, &dstkey);
|
||||
@@ -1178,18 +1185,20 @@ setup_file_key(void) {
|
||||
case DST_ALG_HMACSHA512:
|
||||
hmacname = DNS_TSIG_HMACSHA512_NAME;
|
||||
break;
|
||||
default:
|
||||
printf(";; Couldn't create key %s: bad algorithm\n",
|
||||
keynametext);
|
||||
goto failure;
|
||||
}
|
||||
result = dns_tsigkey_createfromkey(dst_key_name(dstkey), hmacname,
|
||||
dstkey, false, NULL, 0, 0, mctx,
|
||||
NULL, &tsigkey);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
printf(";; Couldn't create key %s: %s\n", keynametext,
|
||||
isc_result_totext(result));
|
||||
goto failure;
|
||||
|
||||
if (hmacname != NULL) {
|
||||
result = dns_tsigkey_createfromkey(
|
||||
dst_key_name(dstkey), hmacname, dstkey, false, NULL, 0,
|
||||
0, mctx, NULL, &tsigkey);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
printf(";; Couldn't create key %s: %s\n", keynametext,
|
||||
isc_result_totext(result));
|
||||
goto failure;
|
||||
}
|
||||
} else {
|
||||
dst_key_attach(dstkey, &sig0key);
|
||||
dst_key_free(&dstkey);
|
||||
}
|
||||
failure:
|
||||
if (dstkey != NULL) {
|
||||
@@ -2425,6 +2434,15 @@ setup_lookup(dig_lookup_t *lookup) {
|
||||
debug("initializing keys");
|
||||
result = dns_message_settsigkey(lookup->sendmsg, tsigkey);
|
||||
check_result(result, "dns_message_settsigkey");
|
||||
} else if (sig0key != NULL) {
|
||||
debug("initializing keys");
|
||||
result = dns_message_setsig0key(lookup->sendmsg, sig0key);
|
||||
check_result(result, "dns_message_setsig0key");
|
||||
}
|
||||
|
||||
if (lookup->fuzzing) {
|
||||
lookup->sendmsg->fuzzing = true;
|
||||
lookup->sendmsg->fuzztime = lookup->fuzztime;
|
||||
}
|
||||
|
||||
lookup->sendspace = isc_mem_get(mctx, COMMSIZE);
|
||||
@@ -4654,10 +4672,17 @@ destroy_libs(void) {
|
||||
clear_searchlist();
|
||||
|
||||
if (tsigkey != NULL) {
|
||||
debug("freeing key %p", tsigkey);
|
||||
debug("freeing TSIG key %p", tsigkey);
|
||||
dns_tsigkey_detach(&tsigkey);
|
||||
}
|
||||
|
||||
if (sig0key != NULL) {
|
||||
debug("freeing SIG(0) key %p", sig0key);
|
||||
dst_key_free(&sig0key);
|
||||
}
|
||||
|
||||
if (namebuf != NULL) {
|
||||
debug("freeing key %p", tsigkey);
|
||||
isc_buffer_free(&namebuf);
|
||||
}
|
||||
|
||||
|
@@ -108,10 +108,11 @@ struct dig_lookup {
|
||||
isc_refcount_t references;
|
||||
bool aaonly, adflag, badcookie, besteffort, cdflag, cleared, comments,
|
||||
dns64prefix, dnssec, doing_xfr, done_as_is, ednsneg, expandaaaa,
|
||||
expire, header_only, identify, /*%< Append an "on server <foo>"
|
||||
message */
|
||||
identify_previous_line, /*% Prepend a "Nameserver <foo>:"
|
||||
message, with newline and tab */
|
||||
expire, fuzzing, header_only, identify, /*%< Append an "on
|
||||
server <foo>" message
|
||||
*/
|
||||
identify_previous_line, /*% Prepend a "Nameserver <foo>:"
|
||||
message, with newline and tab */
|
||||
idnin, idnout, ignore, multiline, need_search, new_search,
|
||||
noclass, nocrypto, nottl, ns_search_only, /*%< dig +nssearch,
|
||||
host -C */
|
||||
@@ -188,6 +189,7 @@ struct dig_lookup {
|
||||
char *tls_key_file;
|
||||
isc_tlsctx_cache_t *tls_ctx_cache;
|
||||
};
|
||||
isc_stdtime_t fuzztime;
|
||||
};
|
||||
|
||||
/*% The dig_query structure */
|
||||
|
@@ -153,12 +153,14 @@ Print a usage summary.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-k keyfile
|
||||
This option tells \fI\%named\fP to sign queries using TSIG using a key read from the given file. Key
|
||||
files can be generated using \fI\%tsig\-keygen\fP\&. When using TSIG
|
||||
authentication with \fBdig\fP, the name server that is queried needs to
|
||||
know the key and algorithm that is being used. In BIND, this is done
|
||||
by providing appropriate \fBkey\fP and \fBserver\fP statements in
|
||||
\fI\%named.conf\fP\&.
|
||||
This option tells \fBdig\fP to sign queries using TSIG or
|
||||
SIG(0) using a key read from the given file. Key files can be
|
||||
generated using \fI\%tsig\-keygen\fP\&. When using TSIG authentication
|
||||
with \fBdig\fP, the name server that is queried needs to
|
||||
know the key and algorithm that is being used. In BIND, this is
|
||||
done by providing appropriate \fBkey\fP and \fBserver\fP statements
|
||||
in \fI\%named.conf\fP for TSIG and by looking up the KEY record
|
||||
in zone data for SIG(0).
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -448,6 +450,15 @@ resolver behavior.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B +fuzztime[=value], +nofuzztime
|
||||
This option allows the signing time to be specified when generating
|
||||
signed messages. If a value is specified it is the seconds since
|
||||
00:00:00 January 1, 1970 UTC ignoring leap seconds. If no value
|
||||
is specified 1646972129 (Fri 11 Mar 2022 04:15:29 UTC) is used.
|
||||
The default is \fB+nofuzztime\fP and the current time is used.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B +header\-only, +noheader\-only
|
||||
This option sends a query with a DNS header without a question section. The
|
||||
default is to add a question section. The query type and query name
|
||||
|
1
fuzz/.gitignore
vendored
1
fuzz/.gitignore
vendored
@@ -1,6 +1,7 @@
|
||||
/*.dSYM/
|
||||
/*.out/
|
||||
/dns_master_load
|
||||
/dns_message_checksig
|
||||
/dns_message_parse
|
||||
/dns_name_fromtext_target
|
||||
/dns_rdata_fromtext
|
||||
|
@@ -23,6 +23,7 @@ libfuzzmain_la_SOURCES = \
|
||||
|
||||
check_PROGRAMS = \
|
||||
dns_master_load \
|
||||
dns_message_checksig \
|
||||
dns_message_parse \
|
||||
dns_name_fromtext_target \
|
||||
dns_rdata_fromtext \
|
||||
@@ -32,6 +33,7 @@ check_PROGRAMS = \
|
||||
|
||||
EXTRA_DIST = \
|
||||
dns_master_load.in \
|
||||
dns_message_checksig.in \
|
||||
dns_message_parse.in \
|
||||
dns_name_fromtext_target.in \
|
||||
dns_rdata_fromtext.in \
|
||||
|
413
fuzz/dns_message_checksig.c
Normal file
413
fuzz/dns_message_checksig.c
Normal file
@@ -0,0 +1,413 @@
|
||||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <isc/buffer.h>
|
||||
#include <isc/commandline.h>
|
||||
#include <isc/file.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/print.h>
|
||||
#include <isc/result.h>
|
||||
#include <isc/string.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <dns/fixedname.h>
|
||||
#include <dns/message.h>
|
||||
#include <dns/name.h>
|
||||
#include <dns/rcode.h>
|
||||
#include <dns/tsig.h>
|
||||
#include <dns/view.h>
|
||||
#include <dns/zone.h>
|
||||
|
||||
#include "fuzz.h"
|
||||
|
||||
bool debug = false;
|
||||
|
||||
static isc_mem_t *mctx = NULL;
|
||||
|
||||
/*
|
||||
* Packet dumps of validily signed request ./IN/SOA
|
||||
* requests.
|
||||
*
|
||||
* TSIG:
|
||||
*
|
||||
* 0x0000: 600b 0900 006a 1140 0000 0000 0000 0000
|
||||
* 0x0010: 0000 0000 0000 0001 0000 0000 0000 0000
|
||||
* 0x0020: 0000 0000 0000 0001 cc88 0035 006a 007d
|
||||
* 0x0030: 1dfa 0000 0001 0000 0000 0001 0000 0600
|
||||
* 0x0040: 0108 7473 6967 2d6b 6579 0000 fa00 ff00
|
||||
* 0x0050: 0000 0000 3d0b 686d 6163 2d73 6861 3235
|
||||
* 0x0060: 3600 0000 622a cce1 012c 0020 224d 5807
|
||||
* 0x0070: 648d 1400 9d8e fc1c d049 55e9 cc90 2187
|
||||
* 0x0080: 3b5f af5c 8899 dc27 c8df b34b 1dfa 0000
|
||||
* 0x0090: 0000
|
||||
*
|
||||
* SIG(0):
|
||||
*
|
||||
* 0x0000: 6004 0e00 013f 1140 0000 0000 0000 0000
|
||||
* 0x0010: 0000 0000 0000 0001 0000 0000 0000 0000
|
||||
* 0x0020: 0000 0000 0000 0001 c0a7 0035 013f 0152
|
||||
* 0x0030: 0000 0000 0001 0000 0000 0001 0000 0600
|
||||
* 0x0040: 0100 0018 00ff 0000 0000 011b 0000 0800
|
||||
* 0x0050: 0000 0000 622a ce0d 622a cbb5 da71 0773
|
||||
* 0x0060: 6967 306b 6579 0068 988b 27bf 5c89 5270
|
||||
* 0x0070: c5ba ea8b 2e10 0512 9b44 48d3 69de b7ec
|
||||
* 0x0080: 7c67 15f3 6bc7 b0dc 277b e8f1 6979 4c89
|
||||
* 0x0090: 149a 0203 30a1 c0b7 a711 ee8a 8d90 ebb9
|
||||
* 0x00a0: 9e33 dd65 33d5 5d1d 90db cf9c bb6a b346
|
||||
* 0x00b0: 568f a399 71d7 c877 616d 2fb7 0f86 963f
|
||||
* 0x00c0: aa00 850d 180a 9f83 cd4b d115 c79f 64c9
|
||||
* 0x00d0: ff05 e751 6810 28b3 2249 c4ba 2d8d 57ba
|
||||
* 0x00e0: 9aad f1fc b34e c237 9465 04fd fe4d 19c9
|
||||
* 0x00f0: 2368 ec8e 7097 eaea e067 2b9c 06eb c383
|
||||
* 0x0100: e901 a11e 606b 4cce c12a 0e57 8c09 b7cb
|
||||
* 0x0110: 23bb ec05 b68b 1852 9288 b665 fe89 cf62
|
||||
* 0x0120: 0a41 5e5a acbe 6903 cbb7 e7b6 cab4 e4a2
|
||||
* 0x0130: b98f 884f c09d 5b39 c695 c84c 9a92 f110
|
||||
* 0x0140: ccc3 f2ee 313f a2a1 1cda 5aa2 faec d593
|
||||
* 0x0150: 4514 724a 868f 94b9 0547 4dc9 7b73 c85e
|
||||
* 0x0160: 544c 73d4 e892 f9
|
||||
*/
|
||||
|
||||
#define HMACSHA256 "\x0bhmac-sha256"
|
||||
|
||||
static isc_stdtime_t fuzztime = 0x622acce1;
|
||||
static dns_view_t *view = NULL;
|
||||
static dns_tsigkey_t *tsigkey = NULL;
|
||||
static dns_tsig_keyring_t *ring = NULL;
|
||||
static dns_tsig_keyring_t *emptyring = NULL;
|
||||
|
||||
static void
|
||||
cleanup(void) {
|
||||
if (view != NULL) {
|
||||
dns_view_detach(&view);
|
||||
}
|
||||
if (tsigkey != NULL) {
|
||||
dns_tsigkey_detach(&tsigkey);
|
||||
}
|
||||
if (ring != NULL) {
|
||||
dns_tsigkeyring_detach(&ring);
|
||||
}
|
||||
if (emptyring != NULL) {
|
||||
dns_tsigkeyring_detach(&emptyring);
|
||||
}
|
||||
if (mctx != NULL) {
|
||||
isc_mem_detach(&mctx);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
LLVMFuzzerInitialize(int *argc __attribute__((unused)),
|
||||
char ***argv __attribute__((unused))) {
|
||||
isc_result_t result;
|
||||
dns_fixedname_t fixed;
|
||||
dns_name_t *name = dns_fixedname_initname(&fixed);
|
||||
unsigned char secret[16] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff };
|
||||
dns_zone_t *zone = NULL;
|
||||
|
||||
atexit(cleanup);
|
||||
|
||||
isc_mem_create(&mctx);
|
||||
|
||||
result = dst_lib_init(mctx, NULL);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
result = dns_view_create(mctx, dns_rdataclass_in, "view", &view);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
result = dns_tsigkeyring_create(mctx, &ring);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
result = dns_tsigkeyring_create(mctx, &emptyring);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
result = dns_name_fromstring(name, "tsig-key", 0, NULL);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
result = dns_tsigkey_create(name, dns_tsig_hmacsha256_name, secret,
|
||||
sizeof(secret), false, NULL, 0, 0, mctx,
|
||||
ring, &tsigkey);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
result = dns_name_fromstring(name, "sig0key", 0, NULL);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
result = dns_zone_create(&zone, mctx, 0);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
result = dns_zone_setorigin(zone, name);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
dns_zone_setclass(zone, view->rdclass);
|
||||
dns_zone_settype(zone, dns_zone_primary);
|
||||
|
||||
result = dns_zone_setkeydirectory(zone, "dns_message_checksig.data");
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
result = dns_zone_setfile(zone, "dns_message_checksig.data/sig0key.db",
|
||||
dns_masterformat_text,
|
||||
&dns_master_style_default);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
result = dns_zone_load(zone, false);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
result = dns_view_addzone(view, zone);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
dns_view_freeze(view);
|
||||
|
||||
dns_zone_detach(&zone);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
create_message(dns_message_t **messagep, const uint8_t *data, size_t size,
|
||||
bool addasig, bool addtsig) {
|
||||
isc_result_t result;
|
||||
dns_message_t *message = NULL;
|
||||
isc_buffer_t b;
|
||||
unsigned char buf[65535];
|
||||
|
||||
isc_buffer_init(&b, buf, sizeof(buf));
|
||||
|
||||
/* Message ID */
|
||||
isc_buffer_putuint16(&b, 0);
|
||||
|
||||
/* QR, Opcode, other flags = 0, rcode = 0 */
|
||||
isc_buffer_putuint16(&b, (*data & 0x1f) << 11);
|
||||
/* Counts */
|
||||
isc_buffer_putuint16(&b, 1);
|
||||
isc_buffer_putuint16(&b, 0);
|
||||
isc_buffer_putuint16(&b, 0);
|
||||
isc_buffer_putuint16(&b, addasig ? 1 : 0);
|
||||
|
||||
/* Question ./IN/SOA */
|
||||
isc_buffer_putuint8(&b, 0);
|
||||
isc_buffer_putuint16(&b, 6);
|
||||
isc_buffer_putuint16(&b, 1);
|
||||
|
||||
if (addasig) {
|
||||
/* Signature */
|
||||
if (addtsig) {
|
||||
const unsigned char keyname[] = "\x08tsig-key";
|
||||
isc_buffer_putmem(&b, keyname, sizeof(keyname));
|
||||
isc_buffer_putuint16(&b, dns_rdatatype_tsig);
|
||||
isc_buffer_putuint16(&b, dns_rdataclass_any);
|
||||
} else {
|
||||
isc_buffer_putuint8(&b, 0); /* '.' */
|
||||
isc_buffer_putuint16(&b, dns_rdatatype_sig);
|
||||
isc_buffer_putuint16(&b, dns_rdataclass_in);
|
||||
}
|
||||
isc_buffer_putuint32(&b, 0); /* ttl */
|
||||
data++;
|
||||
size--;
|
||||
if (size > isc_buffer_availablelength(&b) - 2) {
|
||||
size = isc_buffer_availablelength(&b) - 2;
|
||||
}
|
||||
isc_buffer_putuint16(&b, size);
|
||||
isc_buffer_putmem(&b, data, size);
|
||||
}
|
||||
|
||||
dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &message);
|
||||
|
||||
result = dns_message_parse(message, &b, 0);
|
||||
if (debug) {
|
||||
fprintf(stderr, "dns_message_parse => %s\n",
|
||||
isc_result_totext(result));
|
||||
}
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_message_detach(&message);
|
||||
} else {
|
||||
if (debug) {
|
||||
char text[200000];
|
||||
isc_buffer_init(&b, text, sizeof(text));
|
||||
|
||||
result = dns_message_totext(
|
||||
message, &dns_master_style_debug, 0, &b);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
fprintf(stderr, "%.*s", (int)b.used, text);
|
||||
} else {
|
||||
fprintf(stderr, "dns_message_totext => %s\n",
|
||||
isc_result_totext(result));
|
||||
}
|
||||
}
|
||||
*messagep = message;
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
int
|
||||
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||
isc_result_t result;
|
||||
dns_message_t *message = NULL;
|
||||
unsigned char query_tsig[23 + 32 + 6] = { 0 };
|
||||
bool addasig = false;
|
||||
bool addtime = false;
|
||||
bool addtsig = false;
|
||||
bool setquerytsig = false;
|
||||
bool settsigkey = false;
|
||||
bool subtime = false;
|
||||
bool withring = false;
|
||||
bool withview = false;
|
||||
|
||||
/*
|
||||
* The first 2 octets affect setup.
|
||||
* Octet 1 determines whether a signature is added and which type
|
||||
* (addasig, addtsig), whether time should be adjusted (addtime,
|
||||
* subtime), whether dns_message_setquerytsig and dns_message_settsigkey
|
||||
* have been called, whether there is a keyring available with the
|
||||
* TSIG key or a view is defined.
|
||||
*
|
||||
* The second octet defines if the message is a response and the
|
||||
* opcode.
|
||||
*/
|
||||
if (size > 65535 || size < 2) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
addasig = (*data & 0x80) != 0;
|
||||
addtime = (*data & 0x40) != 0;
|
||||
addtsig = (*data & 0x20) != 0;
|
||||
setquerytsig = (*data & 0x10) != 0;
|
||||
settsigkey = (*data & 0x08) != 0;
|
||||
subtime = (*data & 0x04) != 0;
|
||||
withring = (*data & 0x02) != 0;
|
||||
withview = (*data & 0x01) != 0;
|
||||
|
||||
data++;
|
||||
size--;
|
||||
|
||||
if (debug) {
|
||||
fprintf(stderr,
|
||||
"addasig=%u addtime=%u addtsig=%u setquerytsig=%u "
|
||||
"settsigkey=%u subtime=%u withring=%u\nwithview=%u\n",
|
||||
addasig, addtime, addtsig, setquerytsig, settsigkey,
|
||||
subtime, withring, withview);
|
||||
}
|
||||
|
||||
result = create_message(&message, data, size, addasig, addtsig);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make time calculations consistent.
|
||||
*/
|
||||
message->fuzzing = 1;
|
||||
message->fuzztime = fuzztime;
|
||||
if (addtime) {
|
||||
message->fuzztime += 1200;
|
||||
}
|
||||
if (subtime) {
|
||||
message->fuzztime -= 1200;
|
||||
}
|
||||
|
||||
if ((message->flags & DNS_MESSAGEFLAG_QR) != 0) {
|
||||
if (setquerytsig) {
|
||||
isc_buffer_t b;
|
||||
unsigned char hmacname[] = HMACSHA256;
|
||||
unsigned char hmac[32] = {
|
||||
0x22, 0x4d, 0x58, 0x07, 0x64, 0x8d, 0x14, 0x00,
|
||||
0x9d, 0x8e, 0xfc, 0x1c, 0xd0, 0x49, 0x55, 0xe9,
|
||||
0xcc, 0x90, 0x21, 0x87, 0x3b, 0x5f, 0xaf, 0x5c,
|
||||
0x88, 0x99, 0xdc, 0x27, 0xc8, 0xdf, 0xb3, 0x4b
|
||||
};
|
||||
|
||||
/*
|
||||
* Valid TSIG rdata for tsig-key over a plain
|
||||
* DNS QUERY for ./SOA/IN with no flags set.
|
||||
*/
|
||||
isc_buffer_init(&b, query_tsig, sizeof(query_tsig));
|
||||
isc_buffer_putmem(&b, hmacname, sizeof(hmacname));
|
||||
isc_buffer_putuint16(&b, 0); /* time high */
|
||||
isc_buffer_putuint32(&b, 0x622abec0); /* time low */
|
||||
isc_buffer_putuint16(&b, 300); /* Fudge */
|
||||
isc_buffer_putuint16(&b, 32); /* Mac Length */
|
||||
/* Mac */
|
||||
isc_buffer_putmem(&b, hmac, 32);
|
||||
isc_buffer_putuint16(&b, 7674); /* Original Id */
|
||||
isc_buffer_putuint16(&b, 0); /* Error */
|
||||
isc_buffer_putuint16(&b, 0); /* Other len */
|
||||
|
||||
dns_message_setquerytsig(message, &b);
|
||||
}
|
||||
}
|
||||
|
||||
if (settsigkey) {
|
||||
result = dns_message_settsigkey(message, tsigkey);
|
||||
if (debug) {
|
||||
fprintf(stderr, "dns_message_settsigkey => %s\n",
|
||||
isc_result_totext(result));
|
||||
}
|
||||
}
|
||||
|
||||
dns_view_setkeyring(view, withring ? ring : emptyring);
|
||||
|
||||
result = dns_message_checksig(message, withview ? view : NULL);
|
||||
if (debug) {
|
||||
char textbuf[64];
|
||||
isc_buffer_t b;
|
||||
|
||||
fprintf(stderr, "dns_message_checksig => %s\n",
|
||||
isc_result_totext(result));
|
||||
isc_buffer_init(&b, textbuf, sizeof(textbuf));
|
||||
dns_tsigrcode_totext(message->tsigstatus, &b);
|
||||
fprintf(stderr, "tsigstatus=%.*s\n", (int)b.used, textbuf);
|
||||
isc_buffer_init(&b, textbuf, sizeof(textbuf));
|
||||
dns_tsigrcode_totext(message->sig0status, &b);
|
||||
fprintf(stderr, "sig0status=%.*s\n", (int)b.used, textbuf);
|
||||
}
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (message != NULL) {
|
||||
dns_message_detach(&message);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
1
fuzz/dns_message_checksig.data/Ksig0key.+008+55921.key
Normal file
1
fuzz/dns_message_checksig.data/Ksig0key.+008+55921.key
Normal file
@@ -0,0 +1 @@
|
||||
sig0key. IN KEY 512 3 8 AwEAAa22lgHi1vAbQvu5ETdTrm2H8rwga9tvyMa6LFiSDyevLvSv0Uo5 uvfrXnxaLdtBMts6e1Ly2piSH9JRbOGMNibOK4EXWhWAn8MII4SWgQAs bFwtiz4HyPn2wScrUQdo8DocKiQJBanesr7vDO8fdA6Rg1e0yAtSeNti e8avx46/HJa6CFs3CoE0sf6oOFSxM954AgCBTXOGNBt1Nt3Bhfqt2qyA TLFii5K1jLDTZDVkoiyDXL1M7wcTwKf9METgj1eQmH3GGlRM/OJ/j8xk ZiFGbL3cipWdiH48031jiV2hlc92mKn8Ya0d9AN6c44piza/JSFydZXw sY32nxzjDbs=
|
13
fuzz/dns_message_checksig.data/Ksig0key.+008+55921.private
Normal file
13
fuzz/dns_message_checksig.data/Ksig0key.+008+55921.private
Normal file
@@ -0,0 +1,13 @@
|
||||
Private-key-format: v1.3
|
||||
Algorithm: 8 (RSASHA256)
|
||||
Modulus: rbaWAeLW8BtC+7kRN1OubYfyvCBr22/IxrosWJIPJ68u9K/RSjm69+tefFot20Ey2zp7UvLamJIf0lFs4Yw2Js4rgRdaFYCfwwgjhJaBACxsXC2LPgfI+fbBJytRB2jwOhwqJAkFqd6yvu8M7x90DpGDV7TIC1J422J7xq/Hjr8clroIWzcKgTSx/qg4VLEz3ngCAIFNc4Y0G3U23cGF+q3arIBMsWKLkrWMsNNkNWSiLINcvUzvBxPAp/0wROCPV5CYfcYaVEz84n+PzGRmIUZsvdyKlZ2IfjzTfWOJXaGVz3aYqfxhrR30A3pzjimLNr8lIXJ1lfCxjfafHOMNuw==
|
||||
PublicExponent: AQAB
|
||||
PrivateExponent: GDfclFkR5ToFGH9rMTRMnP73Q5dzjLgkx4vyHcuzKtxcvAans4+hNj+NazckAy2E+mpzV2j95TJ4wZjSM2RvB5xLwBIc4Dg6oyAHL6Ikoae6gw64cHFOaYb808n8CyqWqfX+QWAz9sRSVZXnTuPViX3A+svR7ejVak9Bzr1NTDm0DFlrhaKVCYA++dKVZerfuNiXT/jQvrc4wMCa7WWsfLsFO8aTNkEhqUnmS9c5VYgr7MkCV4ENDBcISpQc9wElI0hl12QPaSj8iSdk9liYp+HTiOxOyp6BGGuecKAoQijMwrZy4qExdOxvowptll8+nZLtwGRn/un/xvIZY5OLAQ==
|
||||
Prime1: ww3C6jwnrLQik/zxSgC0KuqgHq68cCjiRjwK2/euzs7NkMevFpXvV0cWO8x1/wKC1mszVLsUaKTvH6fzRsXfz5MPihzNzUYFwvobKVLserSxEwHNk+FKUU+q07Kf8WWnCqX5nX9QzVG1q4J8Q44N49I5S480jHLGYbyLZrEYMQE=
|
||||
Prime2: 4/3Ozq/8vRgcO4bieFs4CbZR7C98HiTi65SiLBIKY09mDfCleZI0uurAYBluZJgHS5AC5cdyHFuJr3uKxvD+Mgdlru40U6cSCEdK7HAhyUGZUndWl28wyMEB6Kke1/owxVn0S4RKLPOgFI2668H6JObaqXf0wyY89RdVQP6VQrs=
|
||||
Exponent1: Tbr9MyVX1j5PDVSev5P6OKQZvUB7PeM9ESo6VaCl3CqTxx+cic6ke86LcLcxSrewdkxwP1LydiVMWfwvOcP/RhRf+/Uwmp5OC35qNpSiQuAhNObiCw2b9T1fYU/s52FQKTEtgXNMOxZV5IxyguVoaaLMTG08TsAqiKZ/kyP99QE=
|
||||
Exponent2: Q4qSNKrwLbixzHS2LL+hR0dK17RtiaSV0QKUVIf3qdoAusp6yxwkIOegnBeMm6JqLtl38kh2pq37iRAJWcxVEc8dMYiB2fJZpjgwmwDREYUsfcC611vqUN7UyO8pIwSMZDq045ZKPyzhVJV0NZmemEYHq0LNMO7oCheiewGwiDc=
|
||||
Coefficient: T2u/J4NgyO+OqoLpXBIpTBzqrvDk8tb0feYgsp5d16hHvbXxNkMUR8cI07RdbI9HnEldtmhAnbQ6SvFiy2YYjpw/1Fz2WwdxRqLaDV7UlhrT+CqltvU9d/N/xThBNKDa23Wf5Vat+HRiLHSgzsY1PseVCWN+g4azuK2D8+DLeHE=
|
||||
Created: 20220311073606
|
||||
Publish: 20220311073606
|
||||
Activate: 20220311073606
|
14
fuzz/dns_message_checksig.data/sig0key.db
Normal file
14
fuzz/dns_message_checksig.data/sig0key.db
Normal file
@@ -0,0 +1,14 @@
|
||||
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
;
|
||||
; SPDX-License-Identifier: MPL-2.0
|
||||
;
|
||||
; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
;
|
||||
; See the COPYRIGHT file distributed with this work for additional
|
||||
; information regarding copyright ownership.
|
||||
|
||||
sig0key. 0 IN SOA . . 0 0 0 0 0
|
||||
sig0key. 0 IN NS .
|
||||
sig0key. 0 IN KEY 512 3 8 AwEAAa22lgHi1vAbQvu5ETdTrm2H8rwga9tvyMa6LFiSDyevLvSv0Uo5 uvfrXnxaLdtBMts6e1Ly2piSH9JRbOGMNibOK4EXWhWAn8MII4SWgQAs bFwtiz4HyPn2wScrUQdo8DocKiQJBanesr7vDO8fdA6Rg1e0yAtSeNti e8avx46/HJa6CFs3CoE0sf6oOFSxM954AgCBTXOGNBt1Nt3Bhfqt2qyA TLFii5K1jLDTZDVkoiyDXL1M7wcTwKf9METgj1eQmH3GGlRM/OJ/j8xk ZiFGbL3cipWdiH48031jiV2hlc92mKn8Ya0d9AN6c44piza/JSFydZXw sY32nxzjDbs=
|
BIN
fuzz/dns_message_checksig.in/issue-3547
Normal file
BIN
fuzz/dns_message_checksig.in/issue-3547
Normal file
Binary file not shown.
BIN
fuzz/dns_message_checksig.in/sig0
Normal file
BIN
fuzz/dns_message_checksig.in/sig0
Normal file
Binary file not shown.
BIN
fuzz/dns_message_checksig.in/tsig
Normal file
BIN
fuzz/dns_message_checksig.in/tsig
Normal file
Binary file not shown.
BIN
fuzz/dns_message_checksig.in/tsig-reply
Normal file
BIN
fuzz/dns_message_checksig.in/tsig-reply
Normal file
Binary file not shown.
@@ -967,7 +967,11 @@ dns_dnssec_signmessage(dns_message_t *msg, dst_key_t *key) {
|
||||
sig.labels = 0; /* the root name */
|
||||
sig.originalttl = 0;
|
||||
|
||||
isc_stdtime_get(&now);
|
||||
if (msg->fuzzing) {
|
||||
now = msg->fuzztime;
|
||||
} else {
|
||||
isc_stdtime_get(&now);
|
||||
}
|
||||
sig.timesigned = now - DNS_TSIG_FUDGE;
|
||||
sig.timeexpire = now + DNS_TSIG_FUDGE;
|
||||
|
||||
@@ -1111,7 +1115,12 @@ dns_dnssec_verifymessage(isc_buffer_t *source, dns_message_t *msg,
|
||||
goto failure;
|
||||
}
|
||||
|
||||
isc_stdtime_get(&now);
|
||||
if (msg->fuzzing) {
|
||||
now = msg->fuzztime;
|
||||
} else {
|
||||
isc_stdtime_get(&now);
|
||||
}
|
||||
|
||||
if (isc_serial_lt((uint32_t)now, sig.timesigned)) {
|
||||
result = DNS_R_SIGFUTURE;
|
||||
msg->sig0status = dns_tsigerror_badtime;
|
||||
|
@@ -281,6 +281,7 @@ struct dns_message {
|
||||
unsigned int cc_bad : 1;
|
||||
unsigned int tkey : 1;
|
||||
unsigned int rdclass_set : 1;
|
||||
unsigned int fuzzing : 1;
|
||||
|
||||
unsigned int opt_reserved;
|
||||
unsigned int sig_reserved;
|
||||
@@ -323,6 +324,11 @@ struct dns_message {
|
||||
isc_region_t query;
|
||||
isc_region_t saved;
|
||||
|
||||
/*
|
||||
* Time to be used when fuzzing.
|
||||
*/
|
||||
isc_stdtime_t fuzztime;
|
||||
|
||||
dns_rdatasetorderfunc_t order;
|
||||
dns_sortlist_arg_t order_arg;
|
||||
|
||||
|
@@ -795,7 +795,12 @@ dns_tsig_sign(dns_message_t *msg) {
|
||||
dns_name_init(&tsig.algorithm, NULL);
|
||||
dns_name_clone(key->algorithm, &tsig.algorithm);
|
||||
|
||||
isc_stdtime_get(&now);
|
||||
if (msg->fuzzing) {
|
||||
now = msg->fuzztime;
|
||||
} else {
|
||||
isc_stdtime_get(&now);
|
||||
}
|
||||
|
||||
tsig.timesigned = now + msg->timeadjust;
|
||||
tsig.fudge = DNS_TSIG_FUDGE;
|
||||
|
||||
@@ -1143,7 +1148,11 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
|
||||
/*
|
||||
* Get the current time.
|
||||
*/
|
||||
isc_stdtime_get(&now);
|
||||
if (msg->fuzzing) {
|
||||
now = msg->fuzztime;
|
||||
} else {
|
||||
isc_stdtime_get(&now);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find dns_tsigkey_t based on keyname.
|
||||
@@ -1636,7 +1645,11 @@ tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) {
|
||||
/*
|
||||
* Is the time ok?
|
||||
*/
|
||||
isc_stdtime_get(&now);
|
||||
if (msg->fuzzing) {
|
||||
now = msg->fuzztime;
|
||||
} else {
|
||||
isc_stdtime_get(&now);
|
||||
}
|
||||
|
||||
if (now + msg->timeadjust > tsig.timesigned + tsig.fudge) {
|
||||
msg->tsigstatus = dns_tsigerror_badtime;
|
||||
|
Reference in New Issue
Block a user