1 /*
2  * testcode/unitdname.c - unit test for dname routines.
3  *
4  * Copyright (c) 2007, NLnet Labs. All rights reserved.
5  *
6  * This software is open source.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * Neither the name of the NLNET LABS nor the names of its contributors may
20  * be used to endorse or promote products derived from this software without
21  * specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  *
35  */
36 /**
37  * \file
38  * Calls dname unit tests. Exits with code 1 on a failure.
39  */
40 
41 #include "config.h"
42 #include "util/log.h"
43 #include "testcode/unitmain.h"
44 #include "util/data/dname.h"
45 #include "sldns/sbuffer.h"
46 #include "sldns/str2wire.h"
47 
48 /** put dname into buffer */
49 static sldns_buffer*
dname_to_buf(sldns_buffer * b,const char * str)50 dname_to_buf(sldns_buffer* b, const char* str)
51 {
52 	int e;
53 	size_t len = sldns_buffer_capacity(b);
54 	sldns_buffer_clear(b);
55 	e = sldns_str2wire_dname_buf(str, sldns_buffer_begin(b), &len);
56 	if(e != 0)
57 		fatal_exit("%s ldns: %s", __func__,
58 			sldns_get_errorstr_parse(e));
59 	sldns_buffer_set_position(b, len);
60 	sldns_buffer_flip(b);
61 	return b;
62 }
63 
64 /** test query_dname_len function */
65 static void
dname_test_qdl(sldns_buffer * buff)66 dname_test_qdl(sldns_buffer* buff)
67 {
68 	unit_show_func("util/data/dname.c", "query_dname_len");
69 	unit_assert( query_dname_len(buff) == 0);
70 	unit_assert( query_dname_len(dname_to_buf(buff, ".")) == 1 );
71 	unit_assert( query_dname_len(dname_to_buf(buff, "bla.foo.")) == 9 );
72 	unit_assert( query_dname_len(dname_to_buf(buff, "x.y.z.example.com."
73 		)) == 19 );
74 }
75 
76 /** test query_dname_tolower */
77 static void
dname_test_qdtl(sldns_buffer * buff)78 dname_test_qdtl(sldns_buffer* buff)
79 {
80 	unit_show_func("util/data/dname.c", "query_dname_tolower");
81 	sldns_buffer_write_at(buff, 0, "\012abCDeaBCde\003cOm\000", 16);
82 	query_dname_tolower(sldns_buffer_begin(buff));
83 	unit_assert( memcmp(sldns_buffer_begin(buff),
84 		"\012abcdeabcde\003com\000", 16) == 0);
85 
86 	sldns_buffer_write_at(buff, 0, "\001+\012abC{e-ZYXe\003NET\000", 18);
87 	query_dname_tolower(sldns_buffer_begin(buff));
88 	unit_assert( memcmp(sldns_buffer_begin(buff),
89 		"\001+\012abc{e-zyxe\003net\000", 18) == 0);
90 
91 	sldns_buffer_write_at(buff, 0, "\000", 1);
92 	query_dname_tolower(sldns_buffer_begin(buff));
93 	unit_assert( memcmp(sldns_buffer_begin(buff), "\000", 1) == 0);
94 
95 	sldns_buffer_write_at(buff, 0, "\002NL\000", 4);
96 	query_dname_tolower(sldns_buffer_begin(buff));
97 	unit_assert( memcmp(sldns_buffer_begin(buff), "\002nl\000", 4) == 0);
98 }
99 
100 /** test query_dname_compare */
101 static void
dname_test_query_dname_compare(void)102 dname_test_query_dname_compare(void)
103 {
104 	unit_show_func("util/data/dname.c", "query_dname_compare");
105 	unit_assert(query_dname_compare((uint8_t*)"", (uint8_t*)"") == 0);
106 	unit_assert(query_dname_compare((uint8_t*)"\001a",
107 					(uint8_t*)"\001a") == 0);
108 	unit_assert(query_dname_compare((uint8_t*)"\003abc\001a",
109 					(uint8_t*)"\003abc\001a") == 0);
110 	unit_assert(query_dname_compare((uint8_t*)"\003aBc\001a",
111 					(uint8_t*)"\003AbC\001A") == 0);
112 	unit_assert(query_dname_compare((uint8_t*)"\003abc",
113 					(uint8_t*)"\003abc\001a") == -1);
114 	unit_assert(query_dname_compare((uint8_t*)"\003abc\001a",
115 					(uint8_t*)"\003abc") == +1);
116 	unit_assert(query_dname_compare((uint8_t*)"\003abc\001a",
117 					(uint8_t*)"") == +1);
118 	unit_assert(query_dname_compare((uint8_t*)"",
119 					(uint8_t*)"\003abc\001a") == -1);
120 	unit_assert(query_dname_compare((uint8_t*)"\003abc\001a",
121 					(uint8_t*)"\003xxx\001a") == -1);
122 	unit_assert(query_dname_compare((uint8_t*)"\003axx\001a",
123 					(uint8_t*)"\003abc\001a") == 1);
124 	unit_assert(query_dname_compare((uint8_t*)"\003abc\001a",
125 					(uint8_t*)"\003abc\001Z") == -1);
126 	unit_assert(query_dname_compare((uint8_t*)"\003abc\001Z",
127 					(uint8_t*)"\003abc\001a") == 1);
128 }
129 
130 /** test dname_count_labels */
131 static void
dname_test_count_labels(void)132 dname_test_count_labels(void)
133 {
134 	unit_show_func("util/data/dname.c", "dname_count_labels");
135 	unit_assert(dname_count_labels((uint8_t*)"") == 1);
136 	unit_assert(dname_count_labels((uint8_t*)"\003com") == 2);
137 	unit_assert(dname_count_labels((uint8_t*)"\003org") == 2);
138 	unit_assert(dname_count_labels((uint8_t*)"\007example\003com") == 3);
139 	unit_assert(dname_count_labels((uint8_t*)"\003bla\007example\003com")
140 		== 4);
141 }
142 
143 /** test dname_count_size_labels */
144 static void
dname_test_count_size_labels(void)145 dname_test_count_size_labels(void)
146 {
147 	size_t sz = 0;
148 	unit_show_func("util/data/dname.c", "dname_count_size_labels");
149 	unit_assert(dname_count_size_labels((uint8_t*)"", &sz) == 1);
150 	unit_assert(sz == 1);
151 	unit_assert(dname_count_size_labels((uint8_t*)"\003com", &sz) == 2);
152 	unit_assert(sz == 5);
153 	unit_assert(dname_count_size_labels((uint8_t*)"\003org", &sz) == 2);
154 	unit_assert(sz == 5);
155 	unit_assert(dname_count_size_labels((uint8_t*)"\007example\003com",
156 		&sz) == 3);
157 	unit_assert(sz == 13);
158 	unit_assert(dname_count_size_labels((uint8_t*)"\003bla\007example"
159 		"\003com", &sz) == 4);
160 	unit_assert(sz == 17);
161 }
162 
163 
164 /** test pkt_dname_len */
165 static void
dname_test_pkt_dname_len(sldns_buffer * buff)166 dname_test_pkt_dname_len(sldns_buffer* buff)
167 {
168 	unit_show_func("util/data/dname.c", "pkt_dname_len");
169 	sldns_buffer_clear(buff);
170 	sldns_buffer_write(buff, "\000", 1);
171 	sldns_buffer_flip(buff);
172 	unit_assert( pkt_dname_len(buff) == 1 );
173 	unit_assert( sldns_buffer_position(buff) == 1);
174 
175 	sldns_buffer_clear(buff);
176 	sldns_buffer_write(buff, "\003org\000", 5);
177 	sldns_buffer_flip(buff);
178 	unit_assert( pkt_dname_len(buff) == 5 );
179 	unit_assert( sldns_buffer_position(buff) == 5);
180 
181 	sldns_buffer_clear(buff);
182 	sldns_buffer_write(buff, "\002os\007example\003org\000", 16);
183 	sldns_buffer_flip(buff);
184 	unit_assert( pkt_dname_len(buff) == 16 );
185 	unit_assert( sldns_buffer_position(buff) == 16);
186 
187 	/* invalid compression pointer: to self */
188 	sldns_buffer_clear(buff);
189 	sldns_buffer_write(buff, "\300\000os\007example\003org\000", 17);
190 	sldns_buffer_flip(buff);
191 	unit_assert( pkt_dname_len(buff) == 0 );
192 
193 	/* valid compression pointer */
194 	sldns_buffer_clear(buff);
195 	sldns_buffer_write(buff, "\003com\000\040\300\000", 8);
196 	sldns_buffer_flip(buff);
197 	sldns_buffer_set_position(buff, 6);
198 	unit_assert( pkt_dname_len(buff) == 5 );
199 	unit_assert( sldns_buffer_position(buff) == 8);
200 
201 	/* unknown label type */
202 	sldns_buffer_clear(buff);
203 	sldns_buffer_write(buff, "\002os\107example\003org\000", 16);
204 	sldns_buffer_flip(buff);
205 	unit_assert( pkt_dname_len(buff) == 0 );
206 
207 	/* label too long */
208 	sldns_buffer_clear(buff);
209 	sldns_buffer_write(buff, "\002os\047example\003org\000", 16);
210 	sldns_buffer_flip(buff);
211 	unit_assert( pkt_dname_len(buff) == 0 );
212 
213 	/* label exceeds packet */
214 	sldns_buffer_clear(buff);
215 	sldns_buffer_write(buff, "\002os\007example\007org\004", 16);
216 	sldns_buffer_flip(buff);
217 	unit_assert( pkt_dname_len(buff) == 0 );
218 
219 	/* name very long */
220 	sldns_buffer_clear(buff);
221 	sldns_buffer_write(buff,
222 		"\020a1cdef5555544444"
223 		"\020a2cdef5555544444"
224 		"\020a3cdef5555544444"
225 		"\020a4cdef5555544444"
226 		"\020a5cdef5555544444"
227 		"\020a6cdef5555544444"
228 		"\020a7cdef5555544444"
229 		"\020a8cdef5555544444"
230 		"\020a9cdef5555544444"
231 		"\020aAcdef5555544444"
232 		"\020aBcdef5555544444"
233 		"\020aCcdef5555544444"
234 		"\020aDcdef5555544444"
235 		"\020aEcdef5555544444"	/* 238 up to here */
236 		"\007aabbccd"		/* 246 up to here */
237 		"\007example\000"	/* 255 to here */
238 		, 255);
239 	sldns_buffer_flip(buff);
240 	unit_assert( pkt_dname_len(buff) == 255 );
241 	unit_assert( sldns_buffer_position(buff) == 255);
242 
243 	/* name too long */
244 	sldns_buffer_clear(buff);
245 	sldns_buffer_write(buff,
246 		"\020a1cdef5555544444"
247 		"\020a2cdef5555544444"
248 		"\020a3cdef5555544444"
249 		"\020a4cdef5555544444"
250 		"\020a5cdef5555544444"
251 		"\020a6cdef5555544444"
252 		"\020a7cdef5555544444"
253 		"\020a8cdef5555544444"
254 		"\020a9cdef5555544444"
255 		"\020aAcdef5555544444"
256 		"\020aBcdef5555544444"
257 		"\020aCcdef5555544444"
258 		"\020aXcdef5555544444"
259 		"\020aXcdef5555544444"
260 		"\020aXcdef5555544444"
261 		"\020aDcdef5555544444"
262 		"\020aEcdef5555544444"	/* 238 up to here */
263 		"\007aabbccd"		/* 246 up to here */
264 		"\007example\000"	/* 255 to here */
265 		, 255);
266 	sldns_buffer_flip(buff);
267 	unit_assert( pkt_dname_len(buff) == 0 );
268 }
269 
270 /** test dname_lab_cmp */
271 static void
dname_test_dname_lab_cmp(void)272 dname_test_dname_lab_cmp(void)
273 {
274 	int ml = 0; /* number of labels that matched exactly */
275 	unit_show_func("util/data/dname.c", "dname_lab_cmp");
276 
277 	/* test for equality succeeds */
278 	unit_assert(dname_lab_cmp((uint8_t*)"", 1, (uint8_t*)"", 1, &ml) == 0);
279 	unit_assert(ml == 1);
280 	unit_assert(dname_lab_cmp(
281 		(uint8_t*)"\003net", 2,
282 		(uint8_t*)"\003net", 2,
283 		&ml) == 0);
284 	unit_assert(ml == 2);
285 	unit_assert(dname_lab_cmp(
286 		(uint8_t*)"\007example\003net", 3,
287 		(uint8_t*)"\007example\003net", 3,
288 		&ml) == 0);
289 	unit_assert(ml == 3);
290 	unit_assert(dname_lab_cmp(
291 		(uint8_t*)"\004test\007example\003net", 4,
292 		(uint8_t*)"\004test\007example\003net", 4,
293 		&ml) == 0);
294 	unit_assert(ml == 4);
295 
296 	/* root is smaller than anything else */
297 	unit_assert(dname_lab_cmp(
298 		(uint8_t*)"", 1,
299 		(uint8_t*)"\003net", 2,
300 		&ml) == -1);
301 	unit_assert(ml == 1);
302 	unit_assert(dname_lab_cmp(
303 		(uint8_t*)"\003net", 2,
304 		(uint8_t*)"", 1,
305 		&ml) == 1);
306 	unit_assert(ml == 1);
307 	unit_assert(dname_lab_cmp(
308 		(uint8_t*)"", 1,
309 		(uint8_t*)"\007example\003net", 3,
310 		&ml) == -1);
311 	unit_assert(ml == 1);
312 	unit_assert(dname_lab_cmp(
313 		(uint8_t*)"\007example\003net", 3,
314 		(uint8_t*)"", 1,
315 		&ml) == 1);
316 	unit_assert(ml == 1);
317 
318 	/* label length makes a difference */
319 	unit_assert(dname_lab_cmp(
320 		(uint8_t*)"\004neta", 2,
321 		(uint8_t*)"\003net", 2,
322 		&ml) != 0);
323 	unit_assert(ml == 1);
324 	unit_assert(dname_lab_cmp(
325 		(uint8_t*)"\002ne", 2,
326 		(uint8_t*)"\004neta", 2,
327 		&ml) != 0);
328 	unit_assert(ml == 1);
329 
330 	/* contents follow the zone apex */
331 	unit_assert(dname_lab_cmp(
332 		(uint8_t*)"\003bla\007example\003net", 4,
333 		(uint8_t*)"\007example\003net", 3,
334 		&ml) == 1);
335 	unit_assert(ml == 3);
336 	unit_assert(dname_lab_cmp(
337 		(uint8_t*)"\007example\003net", 3,
338 		(uint8_t*)"\003bla\007example\003net", 4,
339 		&ml) == -1);
340 	unit_assert(ml == 3);
341 
342 	/* label content makes a difference */
343 	unit_assert(dname_lab_cmp(
344 		(uint8_t*)"\003aag\007example\003net", 4,
345 		(uint8_t*)"\003bla\007example\003net", 4,
346 		&ml) == -1);
347 	unit_assert(ml == 3);
348 	unit_assert(dname_lab_cmp(
349 		(uint8_t*)"\003aag\007example\003net", 4,
350 		(uint8_t*)"\003bla\007example\003net", 4,
351 		&ml) == -1);
352 	unit_assert(ml == 3);
353 	unit_assert(dname_lab_cmp(
354 		(uint8_t*)"\003bla\003aag\007example\003net", 5,
355 		(uint8_t*)"\003aag\003bla\007example\003net", 5,
356 		&ml) == -1);
357 	unit_assert(ml == 3);
358 	unit_assert(dname_lab_cmp(
359 		(uint8_t*)"\02sn\003opt\003aag\007example\003net", 6,
360 		(uint8_t*)"\02sn\003opt\003bla\007example\003net", 6,
361 		&ml) == -1);
362 	unit_assert(ml == 3);
363 
364 	/* but lowercase/uppercase does not make a difference. */
365 	unit_assert(dname_lab_cmp(
366 		(uint8_t*)"\003bLa\007examPLe\003net", 4,
367 		(uint8_t*)"\003bla\007eXAmple\003nET", 4,
368 		&ml) == 0);
369 	unit_assert(ml == 4);
370 }
371 
372 /** test dname_subdomain_c */
373 static void
dname_test_subdomain(void)374 dname_test_subdomain(void)
375 {
376 	unit_show_func("util/data/dname.c", "dname_subdomain");
377 	unit_assert(dname_subdomain_c(
378 		(uint8_t*)"",
379 		(uint8_t*)""));
380 	unit_assert(dname_subdomain_c(
381 		(uint8_t*)"\003com",
382 		(uint8_t*)""));
383 	unit_assert(!dname_subdomain_c(
384 		(uint8_t*)"",
385 		(uint8_t*)"\003com"));
386 	unit_assert(dname_subdomain_c(
387 		(uint8_t*)"\007example\003com",
388 		(uint8_t*)"\003com"));
389 	unit_assert(!dname_subdomain_c(
390 		(uint8_t*)"\003com",
391 		(uint8_t*)"\007example\003com"));
392 	unit_assert(dname_subdomain_c(
393 		(uint8_t*)"\007example\003com",
394 		(uint8_t*)""));
395 	unit_assert(!dname_subdomain_c(
396 		(uint8_t*)"\003net",
397 		(uint8_t*)"\003com"));
398 	unit_assert(!dname_subdomain_c(
399 		(uint8_t*)"\003net",
400 		(uint8_t*)"\003org"));
401 	unit_assert(!dname_subdomain_c(
402 		(uint8_t*)"\007example\003net",
403 		(uint8_t*)"\003org"));
404 	unit_assert(!dname_subdomain_c(
405 		(uint8_t*)"\003net",
406 		(uint8_t*)"\007example\003org"));
407 }
408 
409 /** test dname_strict_subdomain */
410 static void
dname_test_strict_subdomain(void)411 dname_test_strict_subdomain(void)
412 {
413 	unit_show_func("util/data/dname.c", "dname_strict_subdomain");
414 	unit_assert(!dname_strict_subdomain(
415 		(uint8_t*)"", 1,
416 		(uint8_t*)"", 1));
417 	unit_assert(dname_strict_subdomain(
418 		(uint8_t*)"\003com", 2,
419 		(uint8_t*)"", 1));
420 	unit_assert(!dname_strict_subdomain(
421 		(uint8_t*)"", 1,
422 		(uint8_t*)"\003com", 2));
423 	unit_assert(dname_strict_subdomain(
424 		(uint8_t*)"\007example\003com", 3,
425 		(uint8_t*)"\003com", 2));
426 	unit_assert(!dname_strict_subdomain(
427 		(uint8_t*)"\003com", 2,
428 		(uint8_t*)"\007example\003com", 3));
429 	unit_assert(dname_strict_subdomain(
430 		(uint8_t*)"\007example\003com", 3,
431 		(uint8_t*)"", 1));
432 	unit_assert(!dname_strict_subdomain(
433 		(uint8_t*)"\003net", 2,
434 		(uint8_t*)"\003com", 2));
435 	unit_assert(!dname_strict_subdomain(
436 		(uint8_t*)"\003net", 2,
437 		(uint8_t*)"\003org", 2));
438 	unit_assert(!dname_strict_subdomain(
439 		(uint8_t*)"\007example\003net", 3,
440 		(uint8_t*)"\003org", 2));
441 	unit_assert(!dname_strict_subdomain(
442 		(uint8_t*)"\003net", 2,
443 		(uint8_t*)"\007example\003org", 3));
444 }
445 
446 /** test dname_is_root */
447 static void
dname_test_isroot(void)448 dname_test_isroot(void)
449 {
450 	unit_show_func("util/data/dname.c", "dname_isroot");
451 	unit_assert(dname_is_root((uint8_t*)"\000"));
452 	unit_assert(!dname_is_root((uint8_t*)"\001a\000"));
453 	unit_assert(!dname_is_root((uint8_t*)"\005abvcd\003com\000"));
454 	/* malformed dname in this test, but should work */
455 	unit_assert(!dname_is_root((uint8_t*)"\077a\000"));
456 	unit_assert(dname_is_root((uint8_t*)"\000"));
457 }
458 
459 /** test dname_remove_label */
460 static void
dname_test_removelabel(void)461 dname_test_removelabel(void)
462 {
463 	uint8_t* orig = (uint8_t*)"\007example\003com\000";
464 	uint8_t* n = orig;
465 	size_t l = 13;
466 	unit_show_func("util/data/dname.c", "dname_remove_label");
467 	dname_remove_label(&n, &l);
468 	unit_assert( n == orig+8 );
469 	unit_assert( l == 5 );
470 	dname_remove_label(&n, &l);
471 	unit_assert( n == orig+12 );
472 	unit_assert( l == 1 );
473 	dname_remove_label(&n, &l);
474 	unit_assert( n == orig+12 );
475 	unit_assert( l == 1 );
476 }
477 
478 /** test dname_signame_label_count */
479 static void
dname_test_sigcount(void)480 dname_test_sigcount(void)
481 {
482 	unit_show_func("util/data/dname.c", "dname_signame_label_count");
483 	unit_assert(dname_signame_label_count((uint8_t*)"\000") == 0);
484 	unit_assert(dname_signame_label_count((uint8_t*)"\001*\000") == 0);
485 	unit_assert(dname_signame_label_count((uint8_t*)"\003xom\000") == 1);
486 	unit_assert(dname_signame_label_count(
487 		(uint8_t*)"\001*\003xom\000") == 1);
488 	unit_assert(dname_signame_label_count(
489 		(uint8_t*)"\007example\003xom\000") == 2);
490 	unit_assert(dname_signame_label_count(
491 		(uint8_t*)"\001*\007example\003xom\000") == 2);
492 	unit_assert(dname_signame_label_count(
493 		(uint8_t*)"\003www\007example\003xom\000") == 3);
494 	unit_assert(dname_signame_label_count(
495 		(uint8_t*)"\001*\003www\007example\003xom\000") == 3);
496 }
497 
498 /** test dname_is_wild routine */
499 static void
dname_test_iswild(void)500 dname_test_iswild(void)
501 {
502 	unit_show_func("util/data/dname.c", "dname_iswild");
503 	unit_assert( !dname_is_wild((uint8_t*)"\000") );
504 	unit_assert( dname_is_wild((uint8_t*)"\001*\000") );
505 	unit_assert( !dname_is_wild((uint8_t*)"\003net\000") );
506 	unit_assert( dname_is_wild((uint8_t*)"\001*\003net\000") );
507 }
508 
509 /** test dname_canonical_compare */
510 static void
dname_test_canoncmp(void)511 dname_test_canoncmp(void)
512 {
513 	unit_show_func("util/data/dname.c", "dname_canonical_compare");
514 	/* equality */
515 	unit_assert( dname_canonical_compare(
516 		(uint8_t*)"\000",
517 		(uint8_t*)"\000"
518 		) == 0);
519 	unit_assert( dname_canonical_compare(
520 		(uint8_t*)"\003net\000",
521 		(uint8_t*)"\003net\000"
522 		) == 0);
523 	unit_assert( dname_canonical_compare(
524 		(uint8_t*)"\007example\003net\000",
525 		(uint8_t*)"\007example\003net\000"
526 		) == 0);
527 	unit_assert( dname_canonical_compare(
528 		(uint8_t*)"\004test\007example\003net\000",
529 		(uint8_t*)"\004test\007example\003net\000"
530 		) == 0);
531 
532 	/* subdomains */
533 	unit_assert( dname_canonical_compare(
534 		(uint8_t*)"\003com",
535 		(uint8_t*)"\000"
536 		) == 1);
537 	unit_assert( dname_canonical_compare(
538 		(uint8_t*)"\000",
539 		(uint8_t*)"\003com"
540 		) == -1);
541 	unit_assert( dname_canonical_compare(
542 		(uint8_t*)"\007example\003com",
543 		(uint8_t*)"\003com"
544 		) == 1);
545 	unit_assert( dname_canonical_compare(
546 		(uint8_t*)"\003com",
547 		(uint8_t*)"\007example\003com"
548 		) == -1);
549 	unit_assert( dname_canonical_compare(
550 		(uint8_t*)"\007example\003com",
551 		(uint8_t*)"\000"
552 		) == 1);
553 	unit_assert( dname_canonical_compare(
554 		(uint8_t*)"\000",
555 		(uint8_t*)"\007example\003com"
556 		) == -1);
557 
558 	/* compare rightmost label */
559 	unit_assert( dname_canonical_compare(
560 		(uint8_t*)"\003com",
561 		(uint8_t*)"\003net"
562 		) == -1);
563 	unit_assert( dname_canonical_compare(
564 		(uint8_t*)"\003net",
565 		(uint8_t*)"\003com"
566 		) == 1);
567 	unit_assert( dname_canonical_compare(
568 		(uint8_t*)"\003net",
569 		(uint8_t*)"\003org"
570 		) == -1);
571 	unit_assert( dname_canonical_compare(
572 		(uint8_t*)"\007example\003net",
573 		(uint8_t*)"\003org"
574 		) == -1);
575 	unit_assert( dname_canonical_compare(
576 		(uint8_t*)"\003org",
577 		(uint8_t*)"\007example\003net"
578 		) == 1);
579 
580 	/* label length makes a difference; but only if rest is equal */
581 	unit_assert( dname_canonical_compare(
582 		(uint8_t*)"\004neta",
583 		(uint8_t*)"\003net"
584 		) == 1);
585 	unit_assert( dname_canonical_compare(
586 		(uint8_t*)"\002ne",
587 		(uint8_t*)"\004neta"
588 		) == -1);
589 
590 	/* label content */
591 	unit_assert( dname_canonical_compare(
592 		(uint8_t*)"\003aag\007example\003net",
593 		(uint8_t*)"\003bla\007example\003net"
594 		) == -1);
595 	unit_assert( dname_canonical_compare(
596 		(uint8_t*)"\003bla\007example\003net",
597 		(uint8_t*)"\003aag\007example\003net"
598 		) == 1);
599 	unit_assert( dname_canonical_compare(
600 		(uint8_t*)"\003bla\003aag\007example\003net",
601 		(uint8_t*)"\003aag\003bla\007example\003net"
602 		) == -1);
603 	unit_assert( dname_canonical_compare(
604 		(uint8_t*)"\02sn\003opt\003aag\007example\003net",
605 		(uint8_t*)"\02sn\003opt\003bla\007example\003net"
606 		) == -1);
607 
608 	/* lowercase during compare */
609 	unit_assert( dname_canonical_compare(
610 		(uint8_t*)"\003bLa\007examPLe\003net",
611 		(uint8_t*)"\003bla\007eXAmple\003nET"
612 		) == 0);
613 
614 	/* example from 4034 */
615 	/* example a.example yljkjljk.a.example Z.a.example zABC.a.EXAMPLE
616 	 z.example \001.z.example *.z.example \200.z.example */
617 	unit_assert( dname_canonical_compare(
618 		(uint8_t*)"",
619 		(uint8_t*)"\007example"
620 		) == -1);
621 	unit_assert( dname_canonical_compare(
622 		(uint8_t*)"\007example",
623 		(uint8_t*)"\001a\007example"
624 		) == -1);
625 	unit_assert( dname_canonical_compare(
626 		(uint8_t*)"\001a\007example",
627 		(uint8_t*)"\010yljkjljk\001a\007example"
628 		) == -1);
629 	unit_assert( dname_canonical_compare(
630 		(uint8_t*)"\010yljkjljk\001a\007example",
631 		(uint8_t*)"\001Z\001a\007example"
632 		) == -1);
633 	unit_assert( dname_canonical_compare(
634 		(uint8_t*)"\001Z\001a\007example",
635 		(uint8_t*)"\004zABC\001a\007EXAMPLE"
636 		) == -1);
637 	unit_assert( dname_canonical_compare(
638 		(uint8_t*)"\004zABC\001a\007EXAMPLE",
639 		(uint8_t*)"\001z\007example"
640 		) == -1);
641 	unit_assert( dname_canonical_compare(
642 		(uint8_t*)"\001z\007example",
643 		(uint8_t*)"\001\001\001z\007example"
644 		) == -1);
645 	unit_assert( dname_canonical_compare(
646 		(uint8_t*)"\001\001\001z\007example",
647 		(uint8_t*)"\001*\001z\007example"
648 		) == -1);
649 	unit_assert( dname_canonical_compare(
650 		(uint8_t*)"\001*\001z\007example",
651 		(uint8_t*)"\001\200\001z\007example"
652 		) == -1);
653 	/* same example in reverse */
654 	unit_assert( dname_canonical_compare(
655 		(uint8_t*)"\007example",
656 		(uint8_t*)""
657 		) == 1);
658 	unit_assert( dname_canonical_compare(
659 		(uint8_t*)"\001a\007example",
660 		(uint8_t*)"\007example"
661 		) == 1);
662 	unit_assert( dname_canonical_compare(
663 		(uint8_t*)"\010yljkjljk\001a\007example",
664 		(uint8_t*)"\001a\007example"
665 		) == 1);
666 	unit_assert( dname_canonical_compare(
667 		(uint8_t*)"\001Z\001a\007example",
668 		(uint8_t*)"\010yljkjljk\001a\007example"
669 		) == 1);
670 	unit_assert( dname_canonical_compare(
671 		(uint8_t*)"\004zABC\001a\007EXAMPLE",
672 		(uint8_t*)"\001Z\001a\007example"
673 		) == 1);
674 	unit_assert( dname_canonical_compare(
675 		(uint8_t*)"\001z\007example",
676 		(uint8_t*)"\004zABC\001a\007EXAMPLE"
677 		) == 1);
678 	unit_assert( dname_canonical_compare(
679 		(uint8_t*)"\001\001\001z\007example",
680 		(uint8_t*)"\001z\007example"
681 		) == 1);
682 	unit_assert( dname_canonical_compare(
683 		(uint8_t*)"\001*\001z\007example",
684 		(uint8_t*)"\001\001\001z\007example"
685 		) == 1);
686 	unit_assert( dname_canonical_compare(
687 		(uint8_t*)"\001\200\001z\007example",
688 		(uint8_t*)"\001*\001z\007example"
689 		) == 1);
690 	/* same example for equality */
691 	unit_assert( dname_canonical_compare(
692 		(uint8_t*)"\007example",
693 		(uint8_t*)"\007example"
694 		) == 0);
695 	unit_assert( dname_canonical_compare(
696 		(uint8_t*)"\001a\007example",
697 		(uint8_t*)"\001a\007example"
698 		) == 0);
699 	unit_assert( dname_canonical_compare(
700 		(uint8_t*)"\010yljkjljk\001a\007example",
701 		(uint8_t*)"\010yljkjljk\001a\007example"
702 		) == 0);
703 	unit_assert( dname_canonical_compare(
704 		(uint8_t*)"\001Z\001a\007example",
705 		(uint8_t*)"\001Z\001a\007example"
706 		) == 0);
707 	unit_assert( dname_canonical_compare(
708 		(uint8_t*)"\004zABC\001a\007EXAMPLE",
709 		(uint8_t*)"\004zABC\001a\007EXAMPLE"
710 		) == 0);
711 	unit_assert( dname_canonical_compare(
712 		(uint8_t*)"\001z\007example",
713 		(uint8_t*)"\001z\007example"
714 		) == 0);
715 	unit_assert( dname_canonical_compare(
716 		(uint8_t*)"\001\001\001z\007example",
717 		(uint8_t*)"\001\001\001z\007example"
718 		) == 0);
719 	unit_assert( dname_canonical_compare(
720 		(uint8_t*)"\001*\001z\007example",
721 		(uint8_t*)"\001*\001z\007example"
722 		) == 0);
723 	unit_assert( dname_canonical_compare(
724 		(uint8_t*)"\001\200\001z\007example",
725 		(uint8_t*)"\001\200\001z\007example"
726 		) == 0);
727 }
728 
729 /** Test dname_get_shared_topdomain */
730 static void
dname_test_topdomain(void)731 dname_test_topdomain(void)
732 {
733 	unit_show_func("util/data/dname.c", "dname_get_shared_topdomain");
734 	unit_assert( query_dname_compare(
735 		dname_get_shared_topdomain(
736 			(uint8_t*)"",
737 			(uint8_t*)""),
738 		(uint8_t*)"") == 0);
739 	unit_assert( query_dname_compare(
740 		dname_get_shared_topdomain(
741 			(uint8_t*)"\003www\007example\003com",
742 			(uint8_t*)"\003www\007example\003com"),
743 		(uint8_t*)"\003www\007example\003com") == 0);
744 	unit_assert( query_dname_compare(
745 		dname_get_shared_topdomain(
746 			(uint8_t*)"\003www\007example\003com",
747 			(uint8_t*)"\003bla\007example\003com"),
748 		(uint8_t*)"\007example\003com") == 0);
749 }
750 
751 /** Test dname_valid */
752 static void
dname_test_valid(void)753 dname_test_valid(void)
754 {
755 	unit_show_func("util/data/dname.c", "dname_valid");
756 	unit_assert( dname_valid(
757 			(uint8_t*)"\003www\007example\003com", 255) == 17);
758 	unit_assert( dname_valid((uint8_t*)"", 255) == 1);
759 	unit_assert( dname_valid( (uint8_t*)
760 		"\020a1cdef5555544444"
761 		"\020a2cdef5555544444"
762 		"\020a3cdef5555544444"
763 		"\020a4cdef5555544444"
764 		"\020a5cdef5555544444"
765 		"\020a6cdef5555544444"
766 		"\020a7cdef5555544444"
767 		"\020a8cdef5555544444"
768 		"\020a9cdef5555544444"
769 		"\020aAcdef5555544444"
770 		"\020aBcdef5555544444"
771 		"\020aCcdef5555544444"
772 		"\020aDcdef5555544444"
773 		"\020aEcdef5555544444"	/* 238 up to here */
774 		"\007aabbccd"		/* 246 up to here */
775 		"\007example\000"	/* 255 to here */
776 		, 255) == 255);
777 	unit_assert( dname_valid( (uint8_t*)
778 		"\020a1cdef5555544444"
779 		"\020a2cdef5555544444"
780 		"\020a3cdef5555544444"
781 		"\020a4cdef5555544444"
782 		"\020a5cdef5555544444"
783 		"\020a6cdef5555544444"
784 		"\020a7cdef5555544444"
785 		"\020a8cdef5555544444"
786 		"\020a9cdef5555544444"
787 		"\020aAcdef5555544444"
788 		"\020aBcdef5555544444"
789 		"\020aCcdef5555544444"
790 		"\020aDcdef5555544444"
791 		"\020aEcdef5555544444"	/* 238 up to here */
792 		"\007aabbccd"		/* 246 up to here */
793 		"\010exampleX\000"	/* 256 to here */
794 		, 4096) == 0);
795 }
796 
797 /** Test dname_has_label */
798 static void
dname_test_has_label(void)799 dname_test_has_label(void)
800 {
801 	unit_show_func("util/data/dname.c", "dname_has_label");
802 	/* label past root label */
803 	unit_assert(dname_has_label((uint8_t*)"\01a\0\01c", 5, (uint8_t*)"\01c") == 0);
804 	/* label not found */
805 	unit_assert(dname_has_label((uint8_t*)"\02ab\01c\0", 6, (uint8_t*)"\01e") == 0);
806 	/* buffer too short */
807 	unit_assert(dname_has_label((uint8_t*)"\02ab\01c\0", 5, (uint8_t*)"\0") == 0);
808 	unit_assert(dname_has_label((uint8_t*)"\1a\0", 2, (uint8_t*)"\0") == 0);
809 	unit_assert(dname_has_label((uint8_t*)"\0", 0, (uint8_t*)"\0") == 0);
810 	unit_assert(dname_has_label((uint8_t*)"\02ab\01c", 4, (uint8_t*)"\01c") == 0);
811 	unit_assert(dname_has_label((uint8_t*)"\02ab\03qwe\06oqieur\03def\01c\0", 19, (uint8_t*)"\01c") == 0);
812 
813 	/* positive cases  */
814 	unit_assert(dname_has_label((uint8_t*)"\0", 1, (uint8_t*)"\0") == 1);
815 	unit_assert(dname_has_label((uint8_t*)"\1a\0", 3, (uint8_t*)"\0") == 1);
816 	unit_assert(dname_has_label((uint8_t*)"\01a\0\01c", 5, (uint8_t*)"\0") == 1);
817 	unit_assert(dname_has_label((uint8_t*)"\02ab\01c", 5, (uint8_t*)"\01c") == 1);
818 	unit_assert(dname_has_label((uint8_t*)"\02ab\01c\0", 10, (uint8_t*)"\0") == 1);
819 	unit_assert(dname_has_label((uint8_t*)"\02ab\01c\0", 7, (uint8_t*)"\0") == 1);
820 	unit_assert(dname_has_label((uint8_t*)"\02ab\03qwe\06oqieur\03def\01c\0", 22, (uint8_t*)"\03def") == 1);
821 	unit_assert(dname_has_label((uint8_t*)"\02ab\03qwe\06oqieur\03def\01c\0", 22, (uint8_t*)"\02ab") == 1);
822 	unit_assert(dname_has_label((uint8_t*)"\02ab\03qwe\06oqieur\03def\01c\0", 22, (uint8_t*)"\01c") == 1);
823 }
824 
825 /** test pkt_dname_tolower */
826 static void
dname_test_pdtl(sldns_buffer * loopbuf,sldns_buffer * boundbuf)827 dname_test_pdtl(sldns_buffer* loopbuf, sldns_buffer* boundbuf)
828 {
829 	unit_show_func("util/data/dname.c", "pkt_dname_tolower");
830 	pkt_dname_tolower(loopbuf, sldns_buffer_at(loopbuf, 12));
831 	pkt_dname_tolower(boundbuf, sldns_buffer_at(boundbuf, 12));
832 }
833 
834 /** setup looped dname and out-of-bounds dname ptr */
835 static void
dname_setup_bufs(sldns_buffer * loopbuf,sldns_buffer * boundbuf)836 dname_setup_bufs(sldns_buffer* loopbuf, sldns_buffer* boundbuf)
837 {
838 	sldns_buffer_write_u16(loopbuf, 0xd54d);  /* id */
839 	sldns_buffer_write_u16(loopbuf, 0x12);    /* flags  */
840 	sldns_buffer_write_u16(loopbuf, 1);       /* qdcount */
841 	sldns_buffer_write_u16(loopbuf, 0);       /* ancount */
842 	sldns_buffer_write_u16(loopbuf, 0);       /* nscount */
843 	sldns_buffer_write_u16(loopbuf, 0);       /* arcount */
844 	sldns_buffer_write_u8(loopbuf, 0xc0); /* PTR back at itself */
845 	sldns_buffer_write_u8(loopbuf, 0x0c);
846 	sldns_buffer_flip(loopbuf);
847 
848 	sldns_buffer_write_u16(boundbuf, 0xd54d);  /* id */
849 	sldns_buffer_write_u16(boundbuf, 0x12);    /* flags  */
850 	sldns_buffer_write_u16(boundbuf, 1);       /* qdcount */
851 	sldns_buffer_write_u16(boundbuf, 0);       /* ancount */
852 	sldns_buffer_write_u16(boundbuf, 0);       /* nscount */
853 	sldns_buffer_write_u16(boundbuf, 0);       /* arcount */
854 	sldns_buffer_write_u8(boundbuf, 0x01); /* len=1 */
855 	sldns_buffer_write_u8(boundbuf, (uint8_t)'A'); /* A. label */
856 	sldns_buffer_write_u8(boundbuf, 0xc0); /* PTR out of bounds */
857 	sldns_buffer_write_u8(boundbuf, 0xcc);
858 	sldns_buffer_flip(boundbuf);
859 }
860 
dname_test(void)861 void dname_test(void)
862 {
863 	sldns_buffer* loopbuf = sldns_buffer_new(14);
864 	sldns_buffer* boundbuf = sldns_buffer_new(16);
865 	sldns_buffer* buff = sldns_buffer_new(65800);
866 	unit_assert(loopbuf && boundbuf && buff);
867 	sldns_buffer_flip(buff);
868 	dname_setup_bufs(loopbuf, boundbuf);
869 	dname_test_qdl(buff);
870 	dname_test_qdtl(buff);
871 	dname_test_pdtl(loopbuf, boundbuf);
872 	dname_test_query_dname_compare();
873 	dname_test_count_labels();
874 	dname_test_count_size_labels();
875 	dname_test_dname_lab_cmp();
876 	dname_test_pkt_dname_len(buff);
877 	dname_test_strict_subdomain();
878 	dname_test_subdomain();
879 	dname_test_isroot();
880 	dname_test_removelabel();
881 	dname_test_sigcount();
882 	dname_test_iswild();
883 	dname_test_canoncmp();
884 	dname_test_topdomain();
885 	dname_test_valid();
886 	dname_test_has_label();
887 	sldns_buffer_free(buff);
888 	sldns_buffer_free(loopbuf);
889 	sldns_buffer_free(boundbuf);
890 }
891