summaryrefslogtreecommitdiffstats
path: root/lib/dns/tests/nsec3param_test.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 07:24:22 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 07:24:22 +0000
commit45d6379135504814ab723b57f0eb8be23393a51d (patch)
treed4f2ec4acca824a8446387a758b0ce4238a4dffa /lib/dns/tests/nsec3param_test.c
parentInitial commit. (diff)
downloadbind9-564253c724404fc788d27ab128f285c1070fe23c.tar.xz
bind9-564253c724404fc788d27ab128f285c1070fe23c.zip
Adding upstream version 1:9.16.44.upstream/1%9.16.44upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'lib/dns/tests/nsec3param_test.c')
-rw-r--r--lib/dns/tests/nsec3param_test.c304
1 files changed, 304 insertions, 0 deletions
diff --git a/lib/dns/tests/nsec3param_test.c b/lib/dns/tests/nsec3param_test.c
new file mode 100644
index 0000000..6fd1fc4
--- /dev/null
+++ b/lib/dns/tests/nsec3param_test.c
@@ -0,0 +1,304 @@
+/*
+ * 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.
+ */
+
+#if HAVE_CMOCKA
+
+#include <sched.h> /* IWYU pragma: keep */
+#include <setjmp.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define UNIT_TESTING
+#include <cmocka.h>
+
+#include <isc/hex.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+#include <dns/db.h>
+#include <dns/nsec3.h>
+#include <dns/result.h>
+
+#include "../zone_p.h"
+#include "dnstest.h"
+
+#define HASH 1
+#define FLAGS 0
+#define ITER 5
+#define SALTLEN 4
+#define SALT "FEDCBA98"
+
+static int
+_setup(void **state) {
+ isc_result_t result;
+
+ UNUSED(state);
+
+ result = dns_test_begin(NULL, false);
+ assert_int_equal(result, ISC_R_SUCCESS);
+
+ return (0);
+}
+
+static int
+_teardown(void **state) {
+ UNUSED(state);
+
+ dns_test_end();
+
+ return (0);
+}
+
+/*%
+ * Structures containing parameters for nsec3param_salttotext_test().
+ */
+typedef struct {
+ dns_hash_t hash;
+ unsigned char flags;
+ dns_iterations_t iterations;
+ unsigned char salt_length;
+ const char *salt;
+} nsec3param_rdata_test_params_t;
+
+typedef struct {
+ nsec3param_rdata_test_params_t lookup;
+ nsec3param_rdata_test_params_t expect;
+ bool resalt;
+ isc_result_t expected_result;
+} nsec3param_change_test_params_t;
+
+static void
+decode_salt(const char *string, unsigned char *salt, size_t saltlen) {
+ isc_buffer_t buf;
+ isc_result_t result;
+
+ isc_buffer_init(&buf, salt, saltlen);
+ result = isc_hex_decodestring(string, &buf);
+ assert_int_equal(result, ISC_R_SUCCESS);
+}
+
+static void
+copy_params(nsec3param_rdata_test_params_t from, dns_rdata_nsec3param_t *to,
+ unsigned char *saltbuf, size_t saltlen) {
+ to->hash = from.hash;
+ to->flags = from.flags;
+ to->iterations = from.iterations;
+ to->salt_length = from.salt_length;
+ if (from.salt == NULL) {
+ to->salt = NULL;
+ } else if (strcmp(from.salt, "-") == 0) {
+ DE_CONST("-", to->salt);
+ } else {
+ decode_salt(from.salt, saltbuf, saltlen);
+ to->salt = saltbuf;
+ }
+}
+
+static nsec3param_rdata_test_params_t
+rdata_fromparams(uint8_t hash, uint8_t flags, uint16_t iter, uint8_t saltlen,
+ const char *salt) {
+ nsec3param_rdata_test_params_t nsec3param;
+ nsec3param.hash = hash;
+ nsec3param.flags = flags;
+ nsec3param.iterations = iter;
+ nsec3param.salt_length = saltlen;
+ nsec3param.salt = salt;
+ return (nsec3param);
+}
+
+/*%
+ * Check whether zone_lookup_nsec3param() finds the correct NSEC3PARAM
+ * and sets the correct parameters to use in dns_zone_setnsec3param().
+ */
+static void
+nsec3param_change_test(const nsec3param_change_test_params_t *test) {
+ dns_zone_t *zone = NULL;
+ dns_rdata_nsec3param_t param, lookup, expect;
+ isc_result_t result;
+ unsigned char lookupsalt[255];
+ unsigned char expectsalt[255];
+ unsigned char saltbuf[255];
+
+ /*
+ * Prepare a zone along with its signing keys.
+ */
+ result = dns_test_makezone("nsec3", &zone, NULL, false);
+ assert_int_equal(result, ISC_R_SUCCESS);
+
+ result = dns_zone_setfile(zone, "testdata/nsec3param/nsec3.db.signed",
+ dns_masterformat_text,
+ &dns_master_style_default);
+ assert_int_equal(result, ISC_R_SUCCESS);
+
+ result = dns_zone_load(zone, false);
+ assert_int_equal(result, ISC_R_SUCCESS);
+
+ /*
+ * Copy parameters.
+ */
+ copy_params(test->lookup, &lookup, lookupsalt, sizeof(lookupsalt));
+ copy_params(test->expect, &expect, expectsalt, sizeof(expectsalt));
+
+ /*
+ * Test dns__zone_lookup_nsec3param().
+ */
+ result = dns__zone_lookup_nsec3param(zone, &lookup, &param, saltbuf,
+ test->resalt);
+ assert_int_equal(result, test->expected_result);
+ assert_int_equal(param.hash, expect.hash);
+ assert_int_equal(param.flags, expect.flags);
+ assert_int_equal(param.iterations, expect.iterations);
+ assert_int_equal(param.salt_length, expect.salt_length);
+ assert_non_null(param.salt);
+ if (expect.salt != NULL) {
+ int ret = memcmp(param.salt, expect.salt, expect.salt_length);
+ assert_true(ret == 0);
+ } else {
+ /*
+ * We don't know what the new salt is, but we can compare it
+ * to the previous salt and test that it has changed.
+ */
+ unsigned char salt[SALTLEN];
+ int ret;
+ decode_salt(SALT, salt, SALTLEN);
+ ret = memcmp(param.salt, salt, SALTLEN);
+ assert_false(ret == 0);
+ }
+
+ /*
+ * Detach.
+ */
+ dns_zone_detach(&zone);
+}
+
+static void
+nsec3param_change(void **state) {
+ size_t i;
+
+ /*
+ * Define tests.
+ */
+ const nsec3param_change_test_params_t tests[] = {
+ /*
+ * 1. Change nothing (don't care about salt).
+ * This should return ISC_R_SUCCESS because we are already
+ * using these NSEC3 parameters.
+ */
+ { rdata_fromparams(HASH, FLAGS, ITER, SALTLEN, NULL),
+ rdata_fromparams(HASH, FLAGS, ITER, SALTLEN, SALT), false,
+ ISC_R_SUCCESS },
+ /*
+ * 2. Change nothing, but force a resalt.
+ * This should change the salt. Set 'expect.salt' to NULL to
+ * test a new salt has been generated.
+ */
+ { rdata_fromparams(HASH, FLAGS, ITER, SALTLEN, NULL),
+ rdata_fromparams(HASH, FLAGS, ITER, SALTLEN, NULL), true,
+ DNS_R_NSEC3RESALT },
+ /*
+ * 3. Change iterations.
+ * The NSEC3 paarameters are not found, and there is no
+ * need to resalt because an explicit salt has been set,
+ * and resalt is not enforced.
+ */
+ { rdata_fromparams(HASH, FLAGS, 10, SALTLEN, SALT),
+ rdata_fromparams(HASH, FLAGS, 10, SALTLEN, SALT), false,
+ ISC_R_NOTFOUND },
+ /*
+ * 4. Change iterations, don't care about the salt.
+ * We don't care about the salt. Since we need to change the
+ * NSEC3 parameters, we will also resalt.
+ */
+ { rdata_fromparams(HASH, FLAGS, 10, SALTLEN, NULL),
+ rdata_fromparams(HASH, FLAGS, 10, SALTLEN, NULL), false,
+ DNS_R_NSEC3RESALT },
+ /*
+ * 5. Change salt length.
+ * Changing salt length means we need to resalt.
+ */
+ { rdata_fromparams(HASH, FLAGS, ITER, 16, NULL),
+ rdata_fromparams(HASH, FLAGS, ITER, 16, NULL), false,
+ DNS_R_NSEC3RESALT },
+ /*
+ * 6. Set explicit salt.
+ * A different salt, so the NSEC3 parameters are not found.
+ * No need to resalt because an explicit salt is available.
+ */
+ { rdata_fromparams(HASH, FLAGS, ITER, 4, "12345678"),
+ rdata_fromparams(HASH, FLAGS, ITER, 4, "12345678"), false,
+ ISC_R_NOTFOUND },
+ /*
+ * 7. Same salt.
+ * Nothing changed, so expect ISC_R_SUCCESS as a result.
+ */
+ { rdata_fromparams(HASH, FLAGS, ITER, SALTLEN, SALT),
+ rdata_fromparams(HASH, FLAGS, ITER, SALTLEN, SALT), false,
+ ISC_R_SUCCESS },
+ /*
+ * 8. Same salt, and force resalt.
+ * Nothing changed, but a resalt is enforced.
+ */
+ { rdata_fromparams(HASH, FLAGS, ITER, SALTLEN, SALT),
+ rdata_fromparams(HASH, FLAGS, ITER, SALTLEN, NULL), true,
+ DNS_R_NSEC3RESALT },
+ /*
+ * 9. No salt.
+ * Change parameters to use no salt. These parameters are
+ * not found, and no new salt needs to be generated.
+ */
+ { rdata_fromparams(HASH, FLAGS, ITER, 0, NULL),
+ rdata_fromparams(HASH, FLAGS, ITER, 0, "-"), true,
+ ISC_R_NOTFOUND },
+ /*
+ * 10. No salt, explicit.
+ * Same as above, but set no salt explicitly.
+ */
+ { rdata_fromparams(HASH, FLAGS, ITER, 0, "-"),
+ rdata_fromparams(HASH, FLAGS, ITER, 0, "-"), true,
+ ISC_R_NOTFOUND },
+ };
+
+ UNUSED(state);
+
+ /*
+ * Run tests.
+ */
+ for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
+ nsec3param_change_test(&tests[i]);
+ }
+}
+
+int
+main(void) {
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test_setup_teardown(nsec3param_change, _setup,
+ _teardown),
+ };
+
+ return (cmocka_run_group_tests(tests, NULL, NULL));
+}
+
+#else /* HAVE_CMOCKA */
+
+#include <stdio.h>
+
+int
+main(void) {
+ printf("1..0 # Skipped: cmocka not available\n");
+ return (SKIPPED_TEST_EXIT_CODE);
+}
+
+#endif /* if HAVE_CMOCKA */