summaryrefslogtreecommitdiffstats
path: root/bin/tests/system/tkey
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--bin/tests/system/tkey/Makefile.in55
-rw-r--r--bin/tests/system/tkey/clean.sh20
-rw-r--r--bin/tests/system/tkey/keycreate.c301
-rw-r--r--bin/tests/system/tkey/keydelete.c242
-rw-r--r--bin/tests/system/tkey/ns1/example.db27
-rw-r--r--bin/tests/system/tkey/ns1/named.conf.in49
-rw-r--r--bin/tests/system/tkey/ns1/setup.sh20
-rw-r--r--bin/tests/system/tkey/setup.sh17
-rw-r--r--bin/tests/system/tkey/tests.sh160
9 files changed, 891 insertions, 0 deletions
diff --git a/bin/tests/system/tkey/Makefile.in b/bin/tests/system/tkey/Makefile.in
new file mode 100644
index 0000000..1e62132
--- /dev/null
+++ b/bin/tests/system/tkey/Makefile.in
@@ -0,0 +1,55 @@
+# 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.
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+VERSION=@BIND9_VERSION@
+
+@BIND9_MAKE_INCLUDES@
+
+CINCLUDES = ${DNS_INCLUDES} ${ISC_INCLUDES} \
+ ${OPENSSL_CFLAGS}
+
+CDEFINES =
+CWARNINGS =
+
+DNSLIBS = ../../../../lib/dns/libdns.@A@ @NO_LIBTOOL_DNSLIBS@
+ISCLIBS = ../../../../lib/isc/libisc.@A@ @NO_LIBTOOL_ISCLIBS@
+
+DNSDEPLIBS = ../../../../lib/dns/libdns.@A@
+ISCDEPLIBS = ../../../../lib/isc/libisc.@A@
+
+DEPLIBS = ${DNSDEPLIBS} ${ISCDEPLIBS}
+
+LIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@
+
+TARGETS = keycreate@EXEEXT@ keydelete@EXEEXT@
+
+CREATEOBJS = keycreate.@O@
+DELETEOBJS = keydelete.@O@
+
+SRCS = keycreate.c keydelete.c
+
+@BIND9_MAKE_RULES@
+
+all: keycreate@EXEEXT@ keydelete@EXEEXT@
+
+keycreate@EXEEXT@: ${CREATEOBJS} ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ ${CREATEOBJS} ${LIBS}
+
+keydelete@EXEEXT@: ${DELETEOBJS} ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ ${DELETEOBJS} ${LIBS}
+
+clean distclean::
+ rm -f ${TARGETS}
+
diff --git a/bin/tests/system/tkey/clean.sh b/bin/tests/system/tkey/clean.sh
new file mode 100644
index 0000000..ac54e79
--- /dev/null
+++ b/bin/tests/system/tkey/clean.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+# 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.
+
+rm -f dig.out.* rndc.out.* ns1/named.conf
+rm -f K* ns1/K*
+rm -f */named.memstats
+rm -f */named.run
+rm -f ns1/_default.tsigkeys
+rm -f ns*/named.lock
+rm -f ns*/managed-keys.bind*
diff --git a/bin/tests/system/tkey/keycreate.c b/bin/tests/system/tkey/keycreate.c
new file mode 100644
index 0000000..c62fec1
--- /dev/null
+++ b/bin/tests/system/tkey/keycreate.c
@@ -0,0 +1,301 @@
+/*
+ * 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 <stdlib.h>
+#include <string.h>
+
+#include <isc/app.h>
+#include <isc/base64.h>
+#include <isc/hash.h>
+#include <isc/log.h>
+#include <isc/managers.h>
+#include <isc/mem.h>
+#include <isc/nonce.h>
+#include <isc/print.h>
+#include <isc/random.h>
+#include <isc/sockaddr.h>
+#include <isc/socket.h>
+#include <isc/task.h>
+#include <isc/timer.h>
+#include <isc/util.h>
+
+#include <pk11/site.h>
+
+#include <dns/dispatch.h>
+#include <dns/fixedname.h>
+#include <dns/keyvalues.h>
+#include <dns/message.h>
+#include <dns/name.h>
+#include <dns/request.h>
+#include <dns/result.h>
+#include <dns/tkey.h>
+#include <dns/tsig.h>
+#include <dns/view.h>
+
+#include <dst/result.h>
+
+#define CHECK(str, x) \
+ { \
+ if ((x) != ISC_R_SUCCESS) { \
+ fprintf(stderr, "I:%s: %s\n", (str), \
+ isc_result_totext(x)); \
+ exit(-1); \
+ } \
+ }
+
+#define RUNCHECK(x) RUNTIME_CHECK((x) == ISC_R_SUCCESS)
+
+#define PORT 5300
+#define TIMEOUT 30
+
+static dst_key_t *ourkey = NULL;
+static isc_mem_t *mctx = NULL;
+static dns_tsigkey_t *tsigkey = NULL, *initialkey = NULL;
+static dns_tsig_keyring_t *ring = NULL;
+static unsigned char noncedata[16];
+static isc_buffer_t nonce;
+static dns_requestmgr_t *requestmgr = NULL;
+static const char *ownername_str = ".";
+
+static void
+recvquery(isc_task_t *task, isc_event_t *event) {
+ dns_requestevent_t *reqev = (dns_requestevent_t *)event;
+ isc_result_t result;
+ dns_message_t *query = NULL, *response = NULL;
+ char keyname[256];
+ isc_buffer_t keynamebuf;
+ int type;
+
+ UNUSED(task);
+
+ REQUIRE(reqev != NULL);
+
+ if (reqev->result != ISC_R_SUCCESS) {
+ fprintf(stderr, "I:request event result: %s\n",
+ isc_result_totext(reqev->result));
+ exit(-1);
+ }
+
+ query = reqev->ev_arg;
+
+ dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response);
+
+ result = dns_request_getresponse(reqev->request, response,
+ DNS_MESSAGEPARSE_PRESERVEORDER);
+ CHECK("dns_request_getresponse", result);
+
+ if (response->rcode != dns_rcode_noerror) {
+ result = ISC_RESULTCLASS_DNSRCODE + response->rcode;
+ fprintf(stderr, "I:response rcode: %s\n",
+ isc_result_totext(result));
+ exit(-1);
+ }
+
+ result = dns_tkey_processdhresponse(query, response, ourkey, &nonce,
+ &tsigkey, ring);
+ CHECK("dns_tkey_processdhresponse", result);
+
+ /*
+ * Yes, this is a hack.
+ */
+ isc_buffer_init(&keynamebuf, keyname, sizeof(keyname));
+ result = dst_key_buildfilename(tsigkey->key, 0, "", &keynamebuf);
+ CHECK("dst_key_buildfilename", result);
+ printf("%.*s\n", (int)isc_buffer_usedlength(&keynamebuf),
+ (char *)isc_buffer_base(&keynamebuf));
+ type = DST_TYPE_PRIVATE | DST_TYPE_PUBLIC | DST_TYPE_KEY;
+ result = dst_key_tofile(tsigkey->key, type, "");
+ CHECK("dst_key_tofile", result);
+
+ dns_message_detach(&query);
+ dns_message_detach(&response);
+ dns_request_destroy(&reqev->request);
+ isc_event_free(&event);
+ isc_app_shutdown();
+ return;
+}
+
+static void
+sendquery(isc_task_t *task, isc_event_t *event) {
+ struct in_addr inaddr;
+ isc_sockaddr_t address;
+ isc_region_t r;
+ isc_result_t result;
+ dns_fixedname_t keyname;
+ dns_fixedname_t ownername;
+ isc_buffer_t namestr, keybuf;
+ unsigned char keydata[9];
+ dns_message_t *query = NULL;
+ dns_request_t *request = NULL;
+ static char keystr[] = "0123456789ab";
+
+ isc_event_free(&event);
+
+ result = ISC_R_FAILURE;
+ if (inet_pton(AF_INET, "10.53.0.1", &inaddr) != 1) {
+ CHECK("inet_pton", result);
+ }
+ isc_sockaddr_fromin(&address, &inaddr, PORT);
+
+ dns_fixedname_init(&keyname);
+ isc_buffer_constinit(&namestr, "tkeytest.", 9);
+ isc_buffer_add(&namestr, 9);
+ result = dns_name_fromtext(dns_fixedname_name(&keyname), &namestr, NULL,
+ 0, NULL);
+ CHECK("dns_name_fromtext", result);
+
+ dns_fixedname_init(&ownername);
+ isc_buffer_constinit(&namestr, ownername_str, strlen(ownername_str));
+ isc_buffer_add(&namestr, strlen(ownername_str));
+ result = dns_name_fromtext(dns_fixedname_name(&ownername), &namestr,
+ NULL, 0, NULL);
+ CHECK("dns_name_fromtext", result);
+
+ isc_buffer_init(&keybuf, keydata, 9);
+ result = isc_base64_decodestring(keystr, &keybuf);
+ CHECK("isc_base64_decodestring", result);
+
+ isc_buffer_usedregion(&keybuf, &r);
+
+ result = dns_tsigkey_create(
+ dns_fixedname_name(&keyname), DNS_TSIG_HMACMD5_NAME,
+ isc_buffer_base(&keybuf), isc_buffer_usedlength(&keybuf), false,
+ NULL, 0, 0, mctx, ring, &initialkey);
+ CHECK("dns_tsigkey_create", result);
+
+ dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &query);
+
+ result = dns_tkey_builddhquery(query, ourkey,
+ dns_fixedname_name(&ownername),
+ DNS_TSIG_HMACMD5_NAME, &nonce, 3600);
+ CHECK("dns_tkey_builddhquery", result);
+
+ result = dns_request_create(requestmgr, query, &address,
+ DNS_REQUESTOPT_TCP, initialkey, TIMEOUT,
+ task, recvquery, query, &request);
+ CHECK("dns_request_create", result);
+}
+
+int
+main(int argc, char *argv[]) {
+ char *ourkeyname = NULL;
+ isc_nm_t *netmgr = NULL;
+ isc_taskmgr_t *taskmgr = NULL;
+ isc_timermgr_t *timermgr = NULL;
+ isc_socketmgr_t *socketmgr = NULL;
+ isc_socket_t *sock = NULL;
+ unsigned int attrs, attrmask;
+ isc_sockaddr_t bind_any;
+ dns_dispatchmgr_t *dispatchmgr = NULL;
+ dns_dispatch_t *dispatchv4 = NULL;
+ dns_view_t *view = NULL;
+ dns_tkeyctx_t *tctx = NULL;
+ isc_log_t *log = NULL;
+ isc_logconfig_t *logconfig = NULL;
+ isc_task_t *task = NULL;
+ isc_result_t result;
+ int type;
+
+ RUNCHECK(isc_app_start());
+
+ if (argc < 2) {
+ fprintf(stderr, "I:no DH key provided\n");
+ exit(-1);
+ }
+ if (strcmp(argv[1], "-r") == 0) {
+ fprintf(stderr, "I:the -r option has been deprecated\n");
+ exit(-1);
+ }
+ ourkeyname = argv[1];
+
+ if (argc >= 3) {
+ ownername_str = argv[2];
+ }
+
+ dns_result_register();
+
+ isc_mem_debugging = ISC_MEM_DEBUGRECORD;
+ isc_mem_create(&mctx);
+
+ isc_log_create(mctx, &log, &logconfig);
+
+ RUNCHECK(dst_lib_init(mctx, NULL));
+
+ RUNCHECK(isc_managers_create(mctx, 1, 0, &netmgr, &taskmgr));
+ RUNCHECK(isc_task_create(taskmgr, 0, &task));
+ RUNCHECK(isc_timermgr_create(mctx, &timermgr));
+ RUNCHECK(isc_socketmgr_create(mctx, &socketmgr));
+ RUNCHECK(dns_dispatchmgr_create(mctx, &dispatchmgr));
+ isc_sockaddr_any(&bind_any);
+ attrs = DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_MAKEQUERY |
+ DNS_DISPATCHATTR_IPV4;
+ attrmask = DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_TCP |
+ DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_IPV6;
+ RUNCHECK(dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, &bind_any,
+ 4096, 4, 2, 3, 5, attrs, attrmask,
+ &dispatchv4));
+ RUNCHECK(dns_requestmgr_create(mctx, timermgr, socketmgr, taskmgr,
+ dispatchmgr, dispatchv4, NULL,
+ &requestmgr));
+
+ RUNCHECK(dns_tsigkeyring_create(mctx, &ring));
+ RUNCHECK(dns_tkeyctx_create(mctx, &tctx));
+
+ RUNCHECK(dns_view_create(mctx, 0, "_test", &view));
+ dns_view_setkeyring(view, ring);
+ dns_tsigkeyring_detach(&ring);
+
+ RUNCHECK(isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp,
+ &sock));
+
+ RUNCHECK(isc_app_onrun(mctx, task, sendquery, NULL));
+
+ type = DST_TYPE_PUBLIC | DST_TYPE_PRIVATE | DST_TYPE_KEY;
+ result = dst_key_fromnamedfile(ourkeyname, NULL, type, mctx, &ourkey);
+ CHECK("dst_key_fromnamedfile", result);
+
+ isc_buffer_init(&nonce, noncedata, sizeof(noncedata));
+ isc_nonce_buf(noncedata, sizeof(noncedata));
+ isc_buffer_add(&nonce, sizeof(noncedata));
+
+ (void)isc_app_run();
+
+ dns_requestmgr_shutdown(requestmgr);
+ dns_requestmgr_detach(&requestmgr);
+ dns_dispatch_detach(&dispatchv4);
+ dns_dispatchmgr_destroy(&dispatchmgr);
+ isc_task_shutdown(task);
+ isc_task_detach(&task);
+ isc_managers_destroy(&netmgr, &taskmgr);
+ isc_socket_detach(&sock);
+ isc_socketmgr_destroy(&socketmgr);
+ isc_timermgr_destroy(&timermgr);
+
+ dst_key_free(&ourkey);
+ dns_tsigkey_detach(&initialkey);
+ dns_tsigkey_detach(&tsigkey);
+
+ dns_tkeyctx_destroy(&tctx);
+
+ dns_view_detach(&view);
+
+ isc_log_destroy(&log);
+
+ dst_lib_destroy();
+
+ isc_mem_destroy(&mctx);
+
+ isc_app_finish();
+
+ return (0);
+}
diff --git a/bin/tests/system/tkey/keydelete.c b/bin/tests/system/tkey/keydelete.c
new file mode 100644
index 0000000..bd67d39
--- /dev/null
+++ b/bin/tests/system/tkey/keydelete.c
@@ -0,0 +1,242 @@
+/*
+ * 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 <stdlib.h>
+#include <string.h>
+
+#include <isc/app.h>
+#include <isc/base64.h>
+#include <isc/hash.h>
+#include <isc/log.h>
+#include <isc/managers.h>
+#include <isc/mem.h>
+#include <isc/print.h>
+#include <isc/random.h>
+#include <isc/sockaddr.h>
+#include <isc/socket.h>
+#include <isc/task.h>
+#include <isc/timer.h>
+#include <isc/util.h>
+
+#include <pk11/site.h>
+
+#include <dns/dispatch.h>
+#include <dns/fixedname.h>
+#include <dns/keyvalues.h>
+#include <dns/message.h>
+#include <dns/name.h>
+#include <dns/request.h>
+#include <dns/result.h>
+#include <dns/tkey.h>
+#include <dns/tsig.h>
+#include <dns/view.h>
+
+#include <dst/result.h>
+
+#define CHECK(str, x) \
+ { \
+ if ((x) != ISC_R_SUCCESS) { \
+ fprintf(stderr, "I:%s: %s\n", (str), \
+ isc_result_totext(x)); \
+ exit(-1); \
+ } \
+ }
+
+#define RUNCHECK(x) RUNTIME_CHECK((x) == ISC_R_SUCCESS)
+
+#define PORT 5300
+#define TIMEOUT 30
+
+static isc_mem_t *mctx = NULL;
+static dns_tsigkey_t *tsigkey = NULL;
+static dns_tsig_keyring_t *ring = NULL;
+static dns_requestmgr_t *requestmgr = NULL;
+
+static void
+recvquery(isc_task_t *task, isc_event_t *event) {
+ dns_requestevent_t *reqev = (dns_requestevent_t *)event;
+ isc_result_t result;
+ dns_message_t *query = NULL, *response = NULL;
+
+ UNUSED(task);
+
+ REQUIRE(reqev != NULL);
+
+ if (reqev->result != ISC_R_SUCCESS) {
+ fprintf(stderr, "I:request event result: %s\n",
+ isc_result_totext(reqev->result));
+ exit(-1);
+ }
+
+ query = reqev->ev_arg;
+
+ dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response);
+
+ result = dns_request_getresponse(reqev->request, response,
+ DNS_MESSAGEPARSE_PRESERVEORDER);
+ CHECK("dns_request_getresponse", result);
+
+ if (response->rcode != dns_rcode_noerror) {
+ result = ISC_RESULTCLASS_DNSRCODE + response->rcode;
+ fprintf(stderr, "I:response rcode: %s\n",
+ isc_result_totext(result));
+ exit(-1);
+ }
+
+ result = dns_tkey_processdeleteresponse(query, response, ring);
+ CHECK("dns_tkey_processdhresponse", result);
+
+ dns_message_detach(&query);
+ dns_message_detach(&response);
+ dns_request_destroy(&reqev->request);
+ isc_event_free(&event);
+ isc_app_shutdown();
+ return;
+}
+
+static void
+sendquery(isc_task_t *task, isc_event_t *event) {
+ struct in_addr inaddr;
+ isc_sockaddr_t address;
+ isc_result_t result;
+ dns_message_t *query = NULL;
+ dns_request_t *request = NULL;
+
+ isc_event_free(&event);
+
+ result = ISC_R_FAILURE;
+ if (inet_pton(AF_INET, "10.53.0.1", &inaddr) != 1) {
+ CHECK("inet_pton", result);
+ }
+ isc_sockaddr_fromin(&address, &inaddr, PORT);
+
+ dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &query);
+
+ result = dns_tkey_builddeletequery(query, tsigkey);
+ CHECK("dns_tkey_builddeletequery", result);
+
+ result = dns_request_create(requestmgr, query, &address,
+ DNS_REQUESTOPT_TCP, tsigkey, TIMEOUT, task,
+ recvquery, query, &request);
+ CHECK("dns_request_create", result);
+}
+
+int
+main(int argc, char **argv) {
+ char *keyname = NULL;
+ isc_nm_t *netmgr = NULL;
+ isc_taskmgr_t *taskmgr = NULL;
+ isc_timermgr_t *timermgr = NULL;
+ isc_socketmgr_t *socketmgr = NULL;
+ isc_socket_t *sock = NULL;
+ unsigned int attrs, attrmask;
+ isc_sockaddr_t bind_any;
+ dns_dispatchmgr_t *dispatchmgr = NULL;
+ dns_dispatch_t *dispatchv4 = NULL;
+ dns_view_t *view = NULL;
+ dns_tkeyctx_t *tctx = NULL;
+ dst_key_t *dstkey = NULL;
+ isc_log_t *log = NULL;
+ isc_logconfig_t *logconfig = NULL;
+ isc_task_t *task = NULL;
+ isc_result_t result;
+ int type;
+
+ RUNCHECK(isc_app_start());
+
+ if (argc < 2) {
+ fprintf(stderr, "I:no key to delete\n");
+ exit(-1);
+ }
+ if (strcmp(argv[1], "-r") == 0) {
+ fprintf(stderr, "I:The -r options has been deprecated\n");
+ exit(-1);
+ }
+ keyname = argv[1];
+
+ dns_result_register();
+
+ isc_mem_create(&mctx);
+
+ isc_log_create(mctx, &log, &logconfig);
+
+ RUNCHECK(dst_lib_init(mctx, NULL));
+
+ RUNCHECK(isc_managers_create(mctx, 1, 0, &netmgr, &taskmgr));
+ RUNCHECK(isc_task_create(taskmgr, 0, &task));
+ RUNCHECK(isc_timermgr_create(mctx, &timermgr));
+ RUNCHECK(isc_socketmgr_create(mctx, &socketmgr));
+ RUNCHECK(dns_dispatchmgr_create(mctx, &dispatchmgr));
+ isc_sockaddr_any(&bind_any);
+ attrs = DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_MAKEQUERY |
+ DNS_DISPATCHATTR_IPV4;
+ attrmask = DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_TCP |
+ DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_IPV6;
+ RUNCHECK(dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, &bind_any,
+ 4096, 4, 2, 3, 5, attrs, attrmask,
+ &dispatchv4));
+ RUNCHECK(dns_requestmgr_create(mctx, timermgr, socketmgr, taskmgr,
+ dispatchmgr, dispatchv4, NULL,
+ &requestmgr));
+
+ RUNCHECK(dns_tsigkeyring_create(mctx, &ring));
+ RUNCHECK(dns_tkeyctx_create(mctx, &tctx));
+
+ RUNCHECK(dns_view_create(mctx, 0, "_test", &view));
+ dns_view_setkeyring(view, ring);
+
+ RUNCHECK(isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp,
+ &sock));
+
+ RUNCHECK(isc_app_onrun(mctx, task, sendquery, NULL));
+
+ type = DST_TYPE_PUBLIC | DST_TYPE_PRIVATE | DST_TYPE_KEY;
+ result = dst_key_fromnamedfile(keyname, NULL, type, mctx, &dstkey);
+ CHECK("dst_key_fromnamedfile", result);
+ result = dns_tsigkey_createfromkey(dst_key_name(dstkey),
+ DNS_TSIG_HMACMD5_NAME, dstkey, true,
+ NULL, 0, 0, mctx, ring, &tsigkey);
+ dst_key_free(&dstkey);
+ CHECK("dns_tsigkey_createfromkey", result);
+
+ (void)isc_app_run();
+
+ dns_requestmgr_shutdown(requestmgr);
+ dns_requestmgr_detach(&requestmgr);
+ dns_dispatch_detach(&dispatchv4);
+ dns_dispatchmgr_destroy(&dispatchmgr);
+ isc_task_shutdown(task);
+ isc_task_detach(&task);
+ isc_managers_destroy(&netmgr, &taskmgr);
+ isc_socket_detach(&sock);
+ isc_socketmgr_destroy(&socketmgr);
+ isc_timermgr_destroy(&timermgr);
+
+ dns_tsigkeyring_detach(&ring);
+
+ dns_tsigkey_detach(&tsigkey);
+
+ dns_tkeyctx_destroy(&tctx);
+
+ dns_view_detach(&view);
+
+ isc_log_destroy(&log);
+
+ dst_lib_destroy();
+
+ isc_mem_destroy(&mctx);
+
+ isc_app_finish();
+
+ return (0);
+}
diff --git a/bin/tests/system/tkey/ns1/example.db b/bin/tests/system/tkey/ns1/example.db
new file mode 100644
index 0000000..a847946
--- /dev/null
+++ b/bin/tests/system/tkey/ns1/example.db
@@ -0,0 +1,27 @@
+; 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.
+
+$TTL 1D
+
+@ IN SOA ns hostmaster (
+ 1
+ 3600
+ 1800
+ 1814400
+ 3
+ )
+ NS ns
+ns A 10.53.0.1
+mx MX 10 mail
+a A 10.53.0.1
+ A 10.53.0.2
+txt TXT "this is text"
+
diff --git a/bin/tests/system/tkey/ns1/named.conf.in b/bin/tests/system/tkey/ns1/named.conf.in
new file mode 100644
index 0000000..c183880
--- /dev/null
+++ b/bin/tests/system/tkey/ns1/named.conf.in
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+controls { /* empty */ };
+
+options {
+ query-source address 10.53.0.1;
+ notify-source 10.53.0.1;
+ transfer-source 10.53.0.1;
+ port 5300;
+ pid-file "named.pid";
+ listen-on { 10.53.0.1; };
+ listen-on-v6 { none; };
+ recursion no;
+ notify no;
+ tkey-domain "server";
+ tkey-dhkey "server" KEYID;
+ allow-query-cache { any; };
+};
+
+key rndc_key {
+ secret "1234abcd8765";
+ algorithm hmac-sha256;
+};
+
+controls {
+ inet 10.53.0.1 port 9953 allow { any; } keys { rndc_key; };
+};
+
+key "tkeytest." {
+ algorithm hmac-md5;
+ secret "0123456789ab";
+};
+
+zone example {
+ type primary;
+ file "example.db";
+ allow-query { key tkeytest.; none; };
+};
diff --git a/bin/tests/system/tkey/ns1/setup.sh b/bin/tests/system/tkey/ns1/setup.sh
new file mode 100644
index 0000000..6471905
--- /dev/null
+++ b/bin/tests/system/tkey/ns1/setup.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+# 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.
+
+SYSTEMTESTTOP=../..
+. $SYSTEMTESTTOP/conf.sh
+
+keyname=`$KEYGEN -T KEY -a DH -b 768 -n host server`
+keyid=$(keyfile_to_key_id $keyname)
+rm -f named.conf
+sed -e "s;KEYID;$keyid;" < named.conf.in > named.conf
diff --git a/bin/tests/system/tkey/setup.sh b/bin/tests/system/tkey/setup.sh
new file mode 100644
index 0000000..68a50ad
--- /dev/null
+++ b/bin/tests/system/tkey/setup.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+# 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.
+
+SYSTEMTESTTOP=..
+. $SYSTEMTESTTOP/conf.sh
+
+cd ns1 && $SHELL setup.sh
diff --git a/bin/tests/system/tkey/tests.sh b/bin/tests/system/tkey/tests.sh
new file mode 100644
index 0000000..ca466e4
--- /dev/null
+++ b/bin/tests/system/tkey/tests.sh
@@ -0,0 +1,160 @@
+#!/bin/sh
+
+# 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.
+
+SYSTEMTESTTOP=..
+. $SYSTEMTESTTOP/conf.sh
+
+DIGOPTS="@10.53.0.1 -p 5300"
+
+status=0
+n=1
+
+echo_i "generating new DH key ($n)"
+ret=0
+dhkeyname=`$KEYGEN -T KEY -a DH -b 768 -n host client` || ret=1
+if [ $ret != 0 ]; then
+ echo_i "failed"
+ status=$((status+ret))
+ echo_i "exit status: $status"
+ exit $status
+fi
+status=`expr $status + $ret`
+n=$((n+1))
+
+for owner in . foo.example.
+do
+ echo_i "creating new key using owner name \"$owner\" ($n)"
+ ret=0
+ keyname=`$KEYCREATE $dhkeyname $owner` || ret=1
+ if [ $ret != 0 ]; then
+ echo_i "failed"
+ status=$((status+ret))
+ echo_i "exit status: $status"
+ exit $status
+ fi
+ status=`expr $status + $ret`
+ n=$((n+1))
+
+ echo_i "checking the new key ($n)"
+ ret=0
+ $DIG $DIGOPTS txt txt.example -k $keyname > dig.out.1 || ret=1
+ grep "status: NOERROR" dig.out.1 > /dev/null || ret=1
+ grep "TSIG.*hmac-md5.*NOERROR" dig.out.1 > /dev/null || ret=1
+ grep "Some TSIG could not be validated" dig.out.1 > /dev/null && ret=1
+ if [ $ret != 0 ]; then
+ echo_i "failed"
+ fi
+ status=`expr $status + $ret`
+ n=$((n+1))
+
+ echo_i "deleting new key ($n)"
+ ret=0
+ $KEYDELETE $keyname || ret=1
+ if [ $ret != 0 ]; then
+ echo_i "failed"
+ fi
+ status=`expr $status + $ret`
+ n=$((n+1))
+
+ echo_i "checking that new key has been deleted ($n)"
+ ret=0
+ $DIG $DIGOPTS txt txt.example -k $keyname > dig.out.2 || ret=1
+ grep "status: NOERROR" dig.out.2 > /dev/null && ret=1
+ grep "TSIG.*hmac-md5.*NOERROR" dig.out.2 > /dev/null && ret=1
+ grep "Some TSIG could not be validated" dig.out.2 > /dev/null || ret=1
+ if [ $ret != 0 ]; then
+ echo_i "failed"
+ fi
+ status=`expr $status + $ret`
+ n=$((n+1))
+done
+
+echo_i "creating new key using owner name bar.example. ($n)"
+ret=0
+keyname=`$KEYCREATE $dhkeyname bar.example.` || ret=1
+if [ $ret != 0 ]; then
+ echo_i "failed"
+ status=$((status+ret))
+ echo_i "exit status: $status"
+ exit $status
+fi
+status=`expr $status + $ret`
+n=$((n+1))
+
+echo_i "checking the key with 'rndc tsig-list' ($n)"
+ret=0
+$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 tsig-list > rndc.out.1
+grep "key \"bar.example.server" rndc.out.1 > /dev/null || ret=1
+if [ $ret != 0 ]; then
+ echo_i "failed"
+fi
+status=`expr $status + $ret`
+n=$((n+1))
+
+echo_i "using key in a request ($n)"
+ret=0
+$DIG $DIGOPTS -k $keyname txt.example txt > dig.out.3 || ret=1
+grep "status: NOERROR" dig.out.3 > /dev/null || ret=1
+if [ $ret != 0 ]; then
+ echo_i "failed"
+fi
+status=`expr $status + $ret`
+n=$((n+1))
+
+echo_i "deleting the key with 'rndc tsig-delete' ($n)"
+ret=0
+$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 tsig-delete bar.example.server > /dev/null || ret=1
+$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 tsig-list > rndc.out.2
+grep "key \"bar.example.server" rndc.out.2 > /dev/null && ret=1
+$DIG $DIGOPTS -k $keyname txt.example txt > dig.out.4 || ret=1
+grep "TSIG could not be validated" dig.out.4 > /dev/null || ret=1
+if [ $ret != 0 ]; then
+ echo_i "failed"
+fi
+status=`expr $status + $ret`
+n=$((n+1))
+
+echo_i "recreating the bar.example. key ($n)"
+ret=0
+keyname=`$KEYCREATE $dhkeyname bar.example.` || ret=1
+if [ $ret != 0 ]; then
+ echo_i "failed"
+ status=$((status+ret))
+ echo_i "exit status: $status"
+ exit $status
+fi
+status=`expr $status + $ret`
+n=$((n+1))
+
+echo_i "checking the new key with 'rndc tsig-list' ($n)"
+ret=0
+$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 tsig-list > rndc.out.3
+grep "key \"bar.example.server" rndc.out.3 > /dev/null || ret=1
+if [ $ret != 0 ]; then
+ echo_i "failed"
+fi
+status=`expr $status + $ret`
+n=$((n+1))
+
+echo_i "using the new key in a request ($n)"
+ret=0
+$DIG $DIGOPTS -k $keyname txt.example txt > dig.out.5 || ret=1
+grep "status: NOERROR" dig.out.5 > /dev/null || ret=1
+if [ $ret != 0 ]; then
+ echo_i "failed"
+fi
+status=`expr $status + $ret`
+n=$((n+1))
+
+echo_i "exit status: $status"
+[ $status -eq 0 ] || exit 1