xref: /netbsd-src/external/mpl/bind/dist/tests/dns/private_test.c (revision 70f7362772ba52b749c976fb5e86e39a8b2c9afc)
1 /*	$NetBSD: private_test.c,v 1.2 2024/02/21 22:52:50 christos Exp $	*/
2 
3 /*
4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5  *
6  * SPDX-License-Identifier: MPL-2.0
7  *
8  * This Source Code Form is subject to the terms of the Mozilla Public
9  * License, v. 2.0. If a copy of the MPL was not distributed with this
10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
11  *
12  * See the COPYRIGHT file distributed with this work for additional
13  * information regarding copyright ownership.
14  */
15 
16 #include <inttypes.h>
17 #include <sched.h> /* IWYU pragma: keep */
18 #include <setjmp.h>
19 #include <stdarg.h>
20 #include <stdbool.h>
21 #include <stddef.h>
22 #include <stdlib.h>
23 #include <unistd.h>
24 
25 #define UNIT_TESTING
26 #include <cmocka.h>
27 
28 #include <isc/buffer.h>
29 #include <isc/util.h>
30 
31 #include <dns/nsec3.h>
32 #include <dns/private.h>
33 #include <dns/rdataclass.h>
34 #include <dns/rdatatype.h>
35 
36 #include <dst/dst.h>
37 
38 #include <tests/dns.h>
39 
40 static dns_rdatatype_t privatetype = 65534;
41 
42 static int
43 setup_test(void **state) {
44 	isc_result_t result;
45 
46 	UNUSED(state);
47 
48 	result = dst_lib_init(mctx, NULL);
49 
50 	if (result != ISC_R_SUCCESS) {
51 		return (1);
52 	}
53 
54 	return (0);
55 }
56 
57 static int
58 teardown_test(void **state) {
59 	UNUSED(state);
60 
61 	dst_lib_destroy();
62 
63 	return (0);
64 }
65 
66 typedef struct {
67 	unsigned char alg;
68 	dns_keytag_t keyid;
69 	bool remove;
70 	bool complete;
71 } signing_testcase_t;
72 
73 typedef struct {
74 	unsigned char hash;
75 	unsigned char flags;
76 	unsigned int iterations;
77 	unsigned long salt;
78 	bool remove;
79 	bool pending;
80 	bool nonsec;
81 } nsec3_testcase_t;
82 
83 static void
84 make_signing(signing_testcase_t *testcase, dns_rdata_t *private,
85 	     unsigned char *buf, size_t len) {
86 	dns_rdata_init(private);
87 
88 	buf[0] = testcase->alg;
89 	buf[1] = (testcase->keyid & 0xff00) >> 8;
90 	buf[2] = (testcase->keyid & 0xff);
91 	buf[3] = testcase->remove;
92 	buf[4] = testcase->complete;
93 	private->data = buf;
94 	private->length = len;
95 	private->type = privatetype;
96 	private->rdclass = dns_rdataclass_in;
97 }
98 
99 static void
100 make_nsec3(nsec3_testcase_t *testcase, dns_rdata_t *private,
101 	   unsigned char *pbuf) {
102 	dns_rdata_nsec3param_t params;
103 	dns_rdata_t nsec3param = DNS_RDATA_INIT;
104 	unsigned char bufdata[BUFSIZ];
105 	isc_buffer_t buf;
106 	uint32_t salt;
107 	unsigned char *sp;
108 	int slen = 4;
109 
110 	/* for simplicity, we're using a maximum salt length of 4 */
111 	salt = htonl(testcase->salt);
112 	sp = (unsigned char *)&salt;
113 	while (slen > 0 && *sp == '\0') {
114 		slen--;
115 		sp++;
116 	}
117 
118 	params.common.rdclass = dns_rdataclass_in;
119 	params.common.rdtype = dns_rdatatype_nsec3param;
120 	params.hash = testcase->hash;
121 	params.iterations = testcase->iterations;
122 	params.salt = sp;
123 	params.salt_length = slen;
124 
125 	params.flags = testcase->flags;
126 	if (testcase->remove) {
127 		params.flags |= DNS_NSEC3FLAG_REMOVE;
128 		if (testcase->nonsec) {
129 			params.flags |= DNS_NSEC3FLAG_NONSEC;
130 		}
131 	} else {
132 		params.flags |= DNS_NSEC3FLAG_CREATE;
133 		if (testcase->pending) {
134 			params.flags |= DNS_NSEC3FLAG_INITIAL;
135 		}
136 	}
137 
138 	isc_buffer_init(&buf, bufdata, sizeof(bufdata));
139 	dns_rdata_fromstruct(&nsec3param, dns_rdataclass_in,
140 			     dns_rdatatype_nsec3param, &params, &buf);
141 
142 	dns_rdata_init(private);
143 
144 	dns_nsec3param_toprivate(&nsec3param, private, privatetype, pbuf,
145 				 DNS_NSEC3PARAM_BUFFERSIZE + 1);
146 }
147 
148 /* convert private signing records to text */
149 ISC_RUN_TEST_IMPL(private_signing_totext) {
150 	dns_rdata_t private;
151 	int i;
152 
153 	signing_testcase_t testcases[] = { { DST_ALG_RSASHA512, 12345, 0, 0 },
154 					   { DST_ALG_RSASHA256, 54321, 1, 0 },
155 					   { DST_ALG_NSEC3RSASHA1, 22222, 0,
156 					     1 },
157 					   { DST_ALG_RSASHA1, 33333, 1, 1 } };
158 	const char *results[] = { "Signing with key 12345/RSASHA512",
159 				  "Removing signatures for key 54321/RSASHA256",
160 				  "Done signing with key 22222/NSEC3RSASHA1",
161 				  ("Done removing signatures for key "
162 				   "33333/RSASHA1") };
163 	int ncases = 4;
164 
165 	UNUSED(state);
166 
167 	for (i = 0; i < ncases; i++) {
168 		unsigned char data[5];
169 		char output[BUFSIZ];
170 		isc_buffer_t buf;
171 
172 		isc_buffer_init(&buf, output, sizeof(output));
173 
174 		make_signing(&testcases[i], &private, data, sizeof(data));
175 		dns_private_totext(&private, &buf);
176 		assert_string_equal(output, results[i]);
177 	}
178 }
179 
180 /* convert private chain records to text */
181 ISC_RUN_TEST_IMPL(private_nsec3_totext) {
182 	dns_rdata_t private;
183 	int i;
184 
185 	nsec3_testcase_t testcases[] = {
186 		{ 1, 0, 1, 0xbeef, 0, 0, 0 },
187 		{ 1, 1, 10, 0xdadd, 0, 0, 0 },
188 		{ 1, 0, 20, 0xbead, 0, 1, 0 },
189 		{ 1, 0, 30, 0xdeaf, 1, 0, 0 },
190 		{ 1, 0, 100, 0xfeedabee, 1, 0, 1 },
191 	};
192 	const char *results[] = { "Creating NSEC3 chain 1 0 1 BEEF",
193 				  "Creating NSEC3 chain 1 1 10 DADD",
194 				  "Pending NSEC3 chain 1 0 20 BEAD",
195 				  ("Removing NSEC3 chain 1 0 30 DEAF / "
196 				   "creating NSEC chain"),
197 				  "Removing NSEC3 chain 1 0 100 FEEDABEE" };
198 	int ncases = 5;
199 
200 	UNUSED(state);
201 
202 	for (i = 0; i < ncases; i++) {
203 		unsigned char data[DNS_NSEC3PARAM_BUFFERSIZE + 1];
204 		char output[BUFSIZ];
205 		isc_buffer_t buf;
206 
207 		isc_buffer_init(&buf, output, sizeof(output));
208 
209 		make_nsec3(&testcases[i], &private, data);
210 		dns_private_totext(&private, &buf);
211 		assert_string_equal(output, results[i]);
212 	}
213 }
214 
215 ISC_TEST_LIST_START
216 ISC_TEST_ENTRY_CUSTOM(private_signing_totext, setup_test, teardown_test)
217 ISC_TEST_ENTRY_CUSTOM(private_nsec3_totext, setup_test, teardown_test)
218 ISC_TEST_LIST_END
219 
220 ISC_TEST_MAIN
221