mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-09-12 04:47:41 +02:00
- xfr-tsig, unit test for tsig_sign_query.
This commit is contained in:
+1
-1
@@ -1333,7 +1333,6 @@ main(int argc, char* argv[])
|
||||
if(NSS_NoDB_Init(".") != SECSuccess)
|
||||
fatal_exit("could not init NSS");
|
||||
#endif /* HAVE_SSL or HAVE_NSS*/
|
||||
tsig_test();
|
||||
authzone_test();
|
||||
neg_test();
|
||||
rnd_test();
|
||||
@@ -1363,6 +1362,7 @@ main(int argc, char* argv[])
|
||||
#ifdef HAVE_NGTCP2
|
||||
doq_test();
|
||||
#endif /* HAVE_NGTCP2 */
|
||||
tsig_test();
|
||||
if(log_get_lock()) {
|
||||
lock_basic_destroy((lock_basic_type*)log_get_lock());
|
||||
}
|
||||
|
||||
+249
-4
@@ -40,15 +40,18 @@
|
||||
#include "config.h"
|
||||
#include "util/tsig.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/net_help.h"
|
||||
#include "testcode/unitmain.h"
|
||||
#include "sldns/parseutil.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "sldns/wire2str.h"
|
||||
#include <ctype.h>
|
||||
|
||||
#define xstr(s) str(s)
|
||||
#define str(s) #s
|
||||
#define SRCDIRSTR xstr(SRCDIR)
|
||||
|
||||
/** verbosity for this file */
|
||||
/** verbosity for this file, 0 no, 1 print some, 2 print packet dumps */
|
||||
static int vtest = 0;
|
||||
|
||||
/**
|
||||
@@ -56,15 +59,28 @@ static int vtest = 0;
|
||||
*
|
||||
* The tsig test files have this syntax. It is made of lines, lines started
|
||||
* with # are a comment. empty lines are ignored.
|
||||
* file_algorithm <name>
|
||||
* file-algorithm <name>
|
||||
* The name is like md5, sha1, sha256 and if the algorithm is not
|
||||
* supported at the test run time, the file is skipped, silently.
|
||||
*
|
||||
* tsig-key:
|
||||
* the following lines define name:, algorithm: and secret:
|
||||
* and it adds a tsig-key that can be used.
|
||||
* del-key <name>
|
||||
* The tsig key is deleted, from the in-memory key table.
|
||||
*
|
||||
* packet
|
||||
* A packet in hex dump, on the following lines. Until 'endpacket'.
|
||||
* It can be used to sign or verify.
|
||||
* check-packet
|
||||
* A packet in hex dump, on the following lines. Until 'endpacket'.
|
||||
* It is compared to the packet buffer, and the test fails if not equal.
|
||||
*
|
||||
* tsig-sign-query <key> <time> <expected result>
|
||||
* It TSIG signs with key name, at timestamp in secs, and the
|
||||
* result of the call is compared with the expected result, and
|
||||
* the test fails if not equal. The result is in the packet buffer.
|
||||
*
|
||||
*/
|
||||
|
||||
/** Clean up first keyword */
|
||||
@@ -137,7 +153,7 @@ tsig_algo_test(char* algo)
|
||||
static void
|
||||
handle_file_algorithm(char* line, int* break_file)
|
||||
{
|
||||
char* algo = get_arg_on_line(line, "file_algorithm");
|
||||
char* algo = get_arg_on_line(line, "file-algorithm");
|
||||
if(!tsig_algo_test(algo)) {
|
||||
if(vtest)
|
||||
printf("algorithm not supported\n");
|
||||
@@ -222,6 +238,229 @@ handle_del_key(char* line, struct tsig_key_table* key_table)
|
||||
printf("deleted key %s\n", name);
|
||||
}
|
||||
|
||||
/** skip whitespace */
|
||||
static void
|
||||
skip_whites(const char** p)
|
||||
{
|
||||
while(1) {
|
||||
while(isspace((unsigned char)**p))
|
||||
(*p)++;
|
||||
if(**p == ';' || **p == '#') {
|
||||
/* comment, skip until newline */
|
||||
while(**p && **p != '\n')
|
||||
(*p)++;
|
||||
if(**p == '\n')
|
||||
(*p)++;
|
||||
} else return;
|
||||
}
|
||||
}
|
||||
|
||||
/** Read hex part into buffer */
|
||||
static int
|
||||
read_hex_segment(char* s, struct sldns_buffer* buf)
|
||||
{
|
||||
uint8_t val;
|
||||
const char* p = s;
|
||||
while(*p) {
|
||||
skip_whites(&p);
|
||||
if(!*p) break;
|
||||
if(sldns_buffer_position(buf) == sldns_buffer_limit(buf)) {
|
||||
printf("read hex: buffer too small\n");
|
||||
return 0;
|
||||
}
|
||||
if(sldns_hexdigit_to_int(*p) == -1) {
|
||||
printf("read hex: not hex: '%c'\n", *p);
|
||||
return 0;
|
||||
}
|
||||
val = sldns_hexdigit_to_int(*p++) << 4;
|
||||
skip_whites(&p);
|
||||
if(!*p) {
|
||||
printf("read hex: expected another, second, hex digit\n");
|
||||
return 0;
|
||||
}
|
||||
if(sldns_hexdigit_to_int(*p) == -1) {
|
||||
printf("read hex: not hex: '%c'\n", *p);
|
||||
return 0;
|
||||
}
|
||||
val |= sldns_hexdigit_to_int(*p++);
|
||||
sldns_buffer_write_u8(buf, (uint8_t)val);
|
||||
skip_whites(&p);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Read hex packet until 'endpacket' */
|
||||
static int
|
||||
read_packet_hex(char* line, struct sldns_buffer* buf, FILE* in,
|
||||
const char* fname)
|
||||
{
|
||||
char l[1024];
|
||||
char* s;
|
||||
sldns_buffer_clear(buf);
|
||||
if(!read_hex_segment(line, buf)) {
|
||||
printf("Could not read hex %s: %s\n", fname, line);
|
||||
return 0;
|
||||
}
|
||||
while(fgets(l, sizeof(l), in)) {
|
||||
line[sizeof(l)-1]=0;
|
||||
s = get_keyword(l);
|
||||
if(strcmp(s, "endpacket") == 0)
|
||||
break;
|
||||
if(!read_hex_segment(s, buf)) {
|
||||
printf("Could not read hex %s: %s\n", fname, s);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
sldns_buffer_flip(buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Handle the packet */
|
||||
static void
|
||||
handle_packet(char* line, struct sldns_buffer* pkt, FILE* in,
|
||||
const char* fname)
|
||||
{
|
||||
char* arg = get_arg_on_line(line, "packet");
|
||||
if(!read_packet_hex(arg, pkt, in, fname))
|
||||
fatal_exit("Could not read packet");
|
||||
if(vtest >= 2) {
|
||||
char* str = sldns_wire2str_pkt(sldns_buffer_begin(pkt),
|
||||
sldns_buffer_limit(pkt));
|
||||
if(str)
|
||||
printf("packet: %s\n", str);
|
||||
else
|
||||
printf("could not wire2str_pkt\n");
|
||||
free(str);
|
||||
}
|
||||
}
|
||||
|
||||
/** Handle the check-packet */
|
||||
static void
|
||||
handle_check_packet(char* line, struct sldns_buffer* pkt, FILE* in,
|
||||
const char* fname)
|
||||
{
|
||||
char* arg = get_arg_on_line(line, "check-packet");
|
||||
uint8_t data[65536];
|
||||
sldns_buffer check;
|
||||
sldns_buffer_init_frm_data(&check, data, sizeof(data));
|
||||
if(!read_packet_hex(arg, &check, in, fname))
|
||||
fatal_exit("Could not read check-packet");
|
||||
if(vtest >= 2) {
|
||||
char* str = sldns_wire2str_pkt(sldns_buffer_begin(&check),
|
||||
sldns_buffer_limit(&check));
|
||||
if(str)
|
||||
printf("check-packet: %s\n", str);
|
||||
else
|
||||
printf("could not wire2str_pkt\n");
|
||||
free(str);
|
||||
}
|
||||
|
||||
/* Compare the packet */
|
||||
if(vtest && (sldns_buffer_limit(pkt) != sldns_buffer_limit(&check) ||
|
||||
memcmp(sldns_buffer_begin(pkt), sldns_buffer_begin(&check),
|
||||
sldns_buffer_limit(pkt)) != 0)) {
|
||||
printf("The packet and check-packet are different\n");
|
||||
if(sldns_buffer_limit(pkt) != sldns_buffer_limit(&check))
|
||||
printf("Lengths are different %d, %d (check)\n",
|
||||
(int)sldns_buffer_limit(pkt),
|
||||
(int)sldns_buffer_limit(&check));
|
||||
else printf("Lengths are the same %d\n",
|
||||
(int)sldns_buffer_limit(pkt));
|
||||
if(vtest >= 2) {
|
||||
char pkthex[64*1024*2+10], checkhex[64*1024*2+10];
|
||||
char *pktstr, *checkstr;
|
||||
hex_ntop(sldns_buffer_begin(pkt), sldns_buffer_limit(pkt),
|
||||
pkthex, sizeof(pkthex));
|
||||
hex_ntop(sldns_buffer_begin(&check), sldns_buffer_limit(&check),
|
||||
checkhex, sizeof(checkhex));
|
||||
printf(" packet: %s\n", pkthex);
|
||||
printf("check-packet: %s\n", checkhex);
|
||||
pktstr = sldns_wire2str_pkt(sldns_buffer_begin(pkt),
|
||||
sldns_buffer_limit(pkt));
|
||||
checkstr = sldns_wire2str_pkt(
|
||||
sldns_buffer_begin(&check),
|
||||
sldns_buffer_limit(&check));
|
||||
if(pktstr)
|
||||
printf(" packet: %s\n", pktstr);
|
||||
else
|
||||
printf(" packet: could not wire2str\n");
|
||||
if(checkstr)
|
||||
printf("check-packet: %s\n", checkstr);
|
||||
else
|
||||
printf("check-packet: could not wire2str\n");
|
||||
free(pktstr);
|
||||
free(checkstr);
|
||||
}
|
||||
}
|
||||
unit_assert(sldns_buffer_limit(pkt) == sldns_buffer_limit(&check) &&
|
||||
memcmp(sldns_buffer_begin(pkt), sldns_buffer_begin(&check),
|
||||
sldns_buffer_limit(pkt)) == 0);
|
||||
if(vtest)
|
||||
printf("check-packet is equal\n");
|
||||
}
|
||||
|
||||
/** Handle the tsig-sign-query */
|
||||
static void
|
||||
handle_tsig_sign_query(char* line, struct tsig_key_table* key_table,
|
||||
struct sldns_buffer* pkt)
|
||||
{
|
||||
char* arg = get_arg_on_line(line, "tsig-sign-query");
|
||||
char* keyname, *s, *timestr, *expectedstr;
|
||||
int expected_result, ret;
|
||||
uint64_t timepoint;
|
||||
struct tsig_data* tsig;
|
||||
size_t pos;
|
||||
|
||||
keyname = arg;
|
||||
s = arg;
|
||||
s = strchr(s, ' ');
|
||||
if(!s || !*s)
|
||||
fatal_exit("expected arguments for %s", arg);
|
||||
*s++ = 0;
|
||||
while(*s && *s == ' ')
|
||||
s++;
|
||||
timestr = s;
|
||||
s = strchr(s, ' ');
|
||||
if(!s || !*s)
|
||||
fatal_exit("expected arguments for %s", arg);
|
||||
*s++ = 0;
|
||||
while(*s && *s == ' ')
|
||||
s++;
|
||||
expectedstr = s;
|
||||
|
||||
timepoint = (uint64_t)atoll(timestr);
|
||||
if(timepoint == 0 && strcmp(timestr, "0") != 0)
|
||||
fatal_exit("expected time argument for %s", timestr);
|
||||
expected_result = atoi(expectedstr);
|
||||
if(expected_result == 0 && strcmp(expectedstr, "0") != 0)
|
||||
fatal_exit("expected int argument for %s", expectedstr);
|
||||
|
||||
if(vtest)
|
||||
printf("tsig-sign-query with %s %d %d\n", keyname,
|
||||
(int)timepoint, expected_result);
|
||||
|
||||
tsig = tsig_create_fromstr(key_table, keyname);
|
||||
if(!tsig)
|
||||
fatal_exit("alloc fail or key not found %s", keyname);
|
||||
|
||||
/* Put position at the end of the packet to sign it. */
|
||||
pos = sldns_buffer_limit(pkt);
|
||||
sldns_buffer_clear(pkt);
|
||||
sldns_buffer_set_position(pkt, pos);
|
||||
|
||||
ret = tsig_sign_query(tsig, pkt, key_table, timepoint);
|
||||
sldns_buffer_flip(pkt);
|
||||
|
||||
if(vtest) {
|
||||
if(ret == expected_result)
|
||||
printf("function ok, %s\n", (ret?"success":"fail"));
|
||||
else
|
||||
printf("function returned %d, expected result %d\n",
|
||||
ret, expected_result);
|
||||
}
|
||||
unit_assert(ret == expected_result);
|
||||
}
|
||||
|
||||
/** Handle one line from the TSIG test file */
|
||||
static void
|
||||
handle_line(char* line, struct tsig_key_table* key_table,
|
||||
@@ -231,12 +470,18 @@ handle_line(char* line, struct tsig_key_table* key_table,
|
||||
char* s = get_keyword(line);
|
||||
if(vtest)
|
||||
printf("line: %s\n", s);
|
||||
if(strncmp(s, "file_algorithm", 14) == 0) {
|
||||
if(strncmp(s, "file-algorithm", 14) == 0) {
|
||||
handle_file_algorithm(s, break_file);
|
||||
} else if(strcmp(s, "tsig-key:") == 0) {
|
||||
handle_tsig_key(key_table, in, fname);
|
||||
} else if(strncmp(s, "delkey", 6) == 0) {
|
||||
handle_del_key(s, key_table);
|
||||
} else if(strncmp(s, "packet", 6) == 0) {
|
||||
handle_packet(s, pkt, in, fname);
|
||||
} else if(strncmp(s, "check-packet", 12) == 0) {
|
||||
handle_check_packet(s, pkt, in, fname);
|
||||
} else if(strncmp(s, "tsig-sign-query", 15) == 0) {
|
||||
handle_tsig_sign_query(s, key_table, pkt);
|
||||
} else if(strncmp(s, "#", 1) == 0) {
|
||||
/* skip comment */
|
||||
} else if(strcmp(s, "") == 0) {
|
||||
|
||||
Reference in New Issue
Block a user