xref: /netbsd-src/external/bsd/ntp/dist/tests/libntp/authkeys.c (revision cdfa2a7ef92791ba9db70a584a1d904730e6fb46)
1*cdfa2a7eSchristos /*	$NetBSD: authkeys.c,v 1.3 2020/05/25 20:47:36 christos Exp $	*/
248f8ae19Schristos 
3f17b710fSchristos /* This file contains test for both libntp/authkeys.c and libntp/authusekey.c */
4f17b710fSchristos 
5f17b710fSchristos #include "config.h"
6f17b710fSchristos 
7f17b710fSchristos #include "ntp.h"
8f17b710fSchristos #include "ntp_stdlib.h"
9f17b710fSchristos #include "ntp_calendar.h"
10f17b710fSchristos 
11f17b710fSchristos #include "unity.h"
12f17b710fSchristos 
13f17b710fSchristos #ifdef OPENSSL
14f17b710fSchristos # include "openssl/err.h"
15f17b710fSchristos # include "openssl/rand.h"
16f17b710fSchristos # include "openssl/evp.h"
17f17b710fSchristos #endif
18ae49d4a4Schristos #include <limits.h>
19f17b710fSchristos 
20f17b710fSchristos u_long current_time = 4;
21f17b710fSchristos int counter = 0;
22f17b710fSchristos 
23a6f3f22fSchristos void setUp(void);
24a6f3f22fSchristos void tearDown(void);
25a6f3f22fSchristos void AddTrustedKey(keyid_t keyno);
26a6f3f22fSchristos void AddUntrustedKey(keyid_t keyno);
27f17b710fSchristos 
28a6f3f22fSchristos 
29a6f3f22fSchristos void
setUp(void)30a6f3f22fSchristos setUp(void)
31f17b710fSchristos {
32f17b710fSchristos 	if (counter == 0) {
33f17b710fSchristos 		counter++;
34f17b710fSchristos 		init_auth(); // causes segfault if called more than once
35f17b710fSchristos 	}
36f17b710fSchristos 	/*
37f17b710fSchristos 	 * init_auth() is called by tests_main.cpp earlier.  It
38f17b710fSchristos 	 * does not initialize global variables like
39f17b710fSchristos 	 * authnumkeys, so let's reset them to zero here.
40f17b710fSchristos 	 */
41f17b710fSchristos 	authnumkeys = 0;
42f17b710fSchristos 
43f17b710fSchristos 	/*
44f17b710fSchristos 	 * Especially, empty the key cache!
45f17b710fSchristos 	 */
46f17b710fSchristos 	cache_keyid = 0;
47f17b710fSchristos 	cache_type = 0;
48f17b710fSchristos 	cache_flags = 0;
49f17b710fSchristos 	cache_secret = NULL;
50f17b710fSchristos 	cache_secretsize = 0;
51f17b710fSchristos }
52f17b710fSchristos 
53a6f3f22fSchristos void
tearDown(void)54a6f3f22fSchristos tearDown(void)
55f17b710fSchristos {
5656f2724eSchristos 	/*NOP*/
57a6f3f22fSchristos }
58f17b710fSchristos 
5956f2724eSchristos 
60f17b710fSchristos static const int KEYTYPE = KEY_TYPE_MD5;
6156f2724eSchristos static char      msgbuf[128];
62f17b710fSchristos 
63a6f3f22fSchristos void
AddTrustedKey(keyid_t keyno)644c290c01Schristos AddTrustedKey(keyid_t keyno)
654c290c01Schristos {
66f17b710fSchristos 	/*
67f17b710fSchristos 	 * We need to add a MD5-key in addition to setting the
68f17b710fSchristos 	 * trust, because authhavekey() requires type != 0.
69f17b710fSchristos 	 */
70ae49d4a4Schristos 	MD5auth_setkey(keyno, KEYTYPE, NULL, 0, NULL);
71f17b710fSchristos 
72f17b710fSchristos 	authtrust(keyno, TRUE);
73f17b710fSchristos }
74f17b710fSchristos 
75a6f3f22fSchristos void
AddUntrustedKey(keyid_t keyno)764c290c01Schristos AddUntrustedKey(keyid_t keyno)
774c290c01Schristos {
78f17b710fSchristos 	authtrust(keyno, FALSE);
79f17b710fSchristos }
80f17b710fSchristos 
8156f2724eSchristos void test_AddTrustedKeys(void);
test_AddTrustedKeys(void)8256f2724eSchristos void test_AddTrustedKeys(void)
834c290c01Schristos {
84f17b710fSchristos 	const keyid_t KEYNO1 = 5;
85f17b710fSchristos 	const keyid_t KEYNO2 = 8;
86f17b710fSchristos 
87f17b710fSchristos 	AddTrustedKey(KEYNO1);
88f17b710fSchristos 	AddTrustedKey(KEYNO2);
89f17b710fSchristos 
90f17b710fSchristos 	TEST_ASSERT_TRUE(authistrusted(KEYNO1));
91f17b710fSchristos 	TEST_ASSERT_TRUE(authistrusted(KEYNO2));
92f17b710fSchristos }
93f17b710fSchristos 
9456f2724eSchristos void test_AddUntrustedKey(void);
test_AddUntrustedKey(void)9556f2724eSchristos void test_AddUntrustedKey(void)
964c290c01Schristos {
97f17b710fSchristos 	const keyid_t KEYNO = 3;
98f17b710fSchristos 
99f17b710fSchristos 	AddUntrustedKey(KEYNO);
100f17b710fSchristos 
101f17b710fSchristos 	TEST_ASSERT_FALSE(authistrusted(KEYNO));
102f17b710fSchristos }
103f17b710fSchristos 
10456f2724eSchristos void test_HaveKeyCorrect(void);
test_HaveKeyCorrect(void)10556f2724eSchristos void test_HaveKeyCorrect(void)
1064c290c01Schristos {
107f17b710fSchristos 	const keyid_t KEYNO = 3;
108f17b710fSchristos 
109f17b710fSchristos 	AddTrustedKey(KEYNO);
110f17b710fSchristos 
111f17b710fSchristos 	TEST_ASSERT_TRUE(auth_havekey(KEYNO));
112f17b710fSchristos 	TEST_ASSERT_TRUE(authhavekey(KEYNO));
113f17b710fSchristos }
114f17b710fSchristos 
11556f2724eSchristos void test_HaveKeyIncorrect(void);
test_HaveKeyIncorrect(void)11656f2724eSchristos void test_HaveKeyIncorrect(void)
1174c290c01Schristos {
118f17b710fSchristos 	const keyid_t KEYNO = 2;
119f17b710fSchristos 
120f17b710fSchristos 	TEST_ASSERT_FALSE(auth_havekey(KEYNO));
121f17b710fSchristos 	TEST_ASSERT_FALSE(authhavekey(KEYNO));
122f17b710fSchristos }
123f17b710fSchristos 
12456f2724eSchristos void test_AddWithAuthUseKey(void);
test_AddWithAuthUseKey(void)12556f2724eSchristos void test_AddWithAuthUseKey(void)
1264c290c01Schristos {
127f17b710fSchristos 	const keyid_t KEYNO = 5;
128f17b710fSchristos 	const char* KEY = "52a";
129f17b710fSchristos 
1304c290c01Schristos 	TEST_ASSERT_TRUE(authusekey(KEYNO, KEYTYPE, (const u_char*)KEY));
131f17b710fSchristos }
132f17b710fSchristos 
13356f2724eSchristos void test_EmptyKey(void);
test_EmptyKey(void)13456f2724eSchristos void test_EmptyKey(void)
1354c290c01Schristos {
136f17b710fSchristos 	const keyid_t KEYNO = 3;
137f17b710fSchristos 	const char* KEY = "";
138f17b710fSchristos 
1394c290c01Schristos 	TEST_ASSERT_FALSE(authusekey(KEYNO, KEYTYPE, (const u_char*)KEY));
140f17b710fSchristos }
141ae49d4a4Schristos 
142ae49d4a4Schristos /* test the implementation of 'auth_log2' -- use a local copy of the code */
143ae49d4a4Schristos 
144ae49d4a4Schristos static u_short
auth_log2(size_t x)145ae49d4a4Schristos auth_log2(
146ae49d4a4Schristos 	size_t x)
147ae49d4a4Schristos {
148ae49d4a4Schristos 	int	s;
149ae49d4a4Schristos 	int	r = 0;
150ae49d4a4Schristos 	size_t  m = ~(size_t)0;
151ae49d4a4Schristos 
152ae49d4a4Schristos 	for (s = sizeof(size_t) / 2 * CHAR_BIT; s != 0; s >>= 1) {
153ae49d4a4Schristos 		m <<= s;
154ae49d4a4Schristos 		if (x & m)
155ae49d4a4Schristos 			r += s;
156ae49d4a4Schristos 		else
157ae49d4a4Schristos 			x <<= s;
158ae49d4a4Schristos 	}
159ae49d4a4Schristos 	return (u_short)r;
160ae49d4a4Schristos }
161ae49d4a4Schristos 
16256f2724eSchristos void test_auth_log2(void);
test_auth_log2(void)16356f2724eSchristos void test_auth_log2(void)
164ae49d4a4Schristos {
165ae49d4a4Schristos 	int	l2;
166ae49d4a4Schristos 	size_t	tv;
167ae49d4a4Schristos 
168ae49d4a4Schristos 	TEST_ASSERT_EQUAL_INT(0, auth_log2(0));
169ae49d4a4Schristos 	TEST_ASSERT_EQUAL_INT(0, auth_log2(1));
170ae49d4a4Schristos 	for (l2 = 1; l2 < sizeof(size_t)*CHAR_BIT; ++l2) {
171ae49d4a4Schristos 		tv = (size_t)1 << l2;
172ae49d4a4Schristos 		TEST_ASSERT_EQUAL_INT(l2, auth_log2(   tv   ));
173ae49d4a4Schristos 		TEST_ASSERT_EQUAL_INT(l2, auth_log2( tv + 1 ));
174ae49d4a4Schristos 		TEST_ASSERT_EQUAL_INT(l2, auth_log2(2*tv - 1));
175ae49d4a4Schristos 	}
176ae49d4a4Schristos }
17756f2724eSchristos 
17856f2724eSchristos /* Converting a string to a host address. Here we use 'getaddrinfo()' in
17956f2724eSchristos  * an independent implementation to avoid cross-reactions with the
18056f2724eSchristos  * object under test. 'inet_pton' is too dangerous to handle it
18156f2724eSchristos  * properly, and ultimate performance is *not* the goal here.
18256f2724eSchristos  */
18356f2724eSchristos static int/*BOOL*/
getaddr(int af,const char * astr,sockaddr_u * addr)18456f2724eSchristos getaddr(
18556f2724eSchristos 	int af,
18656f2724eSchristos 	const char *astr,
18756f2724eSchristos 	sockaddr_u * addr)
18856f2724eSchristos {
18956f2724eSchristos 	struct addrinfo  hint;
19056f2724eSchristos 	struct addrinfo *ares;
19156f2724eSchristos 
19256f2724eSchristos 	memset(&hint, 0, sizeof(hint));
19356f2724eSchristos 	hint.ai_flags = AI_NUMERICHOST;
19456f2724eSchristos 	hint.ai_family = af;
19556f2724eSchristos 	if (getaddrinfo(astr, NULL, &hint, &ares))
19656f2724eSchristos 		return FALSE;
19756f2724eSchristos 	if (ares->ai_addrlen > sizeof(*addr))
19856f2724eSchristos 		memcpy(addr, ares->ai_addr, sizeof(*addr));
19956f2724eSchristos 	else
20056f2724eSchristos 		memcpy(addr, ares->ai_addr, ares->ai_addrlen);
20156f2724eSchristos 	freeaddrinfo(ares);
20256f2724eSchristos 	return TRUE;
20356f2724eSchristos }
20456f2724eSchristos 
20556f2724eSchristos void test_AddrMatch_anull(void);
test_AddrMatch_anull(void)20656f2724eSchristos void test_AddrMatch_anull(void)
20756f2724eSchristos {
20856f2724eSchristos 	/* Check the not-an-address logic with a prefix/check length of
20956f2724eSchristos 	 * zero bits. Any compare with a NULL or AF_UNSPEC address
21056f2724eSchristos 	 * returns inequality (aka FALSE).
21156f2724eSchristos 	 */
21256f2724eSchristos 	sockaddr_u   ip4, ip6, ipn;
21356f2724eSchristos 
21456f2724eSchristos 	memset(&ipn, 0, sizeof(ipn));
21556f2724eSchristos 	AF(&ipn) = AF_UNSPEC;
21656f2724eSchristos 
21756f2724eSchristos 	TEST_ASSERT_TRUE(getaddr(AF_INET , "192.128.1.1", &ip4));
21856f2724eSchristos 	TEST_ASSERT_TRUE(getaddr(AF_INET6, "::1"        , &ip6));
21956f2724eSchristos 
22056f2724eSchristos 	TEST_ASSERT_FALSE(keyacc_amatch(NULL, NULL, 0));
22156f2724eSchristos 	TEST_ASSERT_FALSE(keyacc_amatch(NULL, &ipn, 0));
22256f2724eSchristos 	TEST_ASSERT_FALSE(keyacc_amatch(NULL, &ip4, 0));
22356f2724eSchristos 	TEST_ASSERT_FALSE(keyacc_amatch(NULL, &ip6, 0));
22456f2724eSchristos 
22556f2724eSchristos 	TEST_ASSERT_FALSE(keyacc_amatch(&ipn, NULL, 0));
22656f2724eSchristos 	TEST_ASSERT_FALSE(keyacc_amatch(&ipn, &ipn, 0));
22756f2724eSchristos 	TEST_ASSERT_FALSE(keyacc_amatch(&ipn, &ip4, 0));
22856f2724eSchristos 	TEST_ASSERT_FALSE(keyacc_amatch(&ipn, &ip6, 0));
22956f2724eSchristos 
23056f2724eSchristos 	TEST_ASSERT_FALSE(keyacc_amatch(&ip4, NULL, 0));
23156f2724eSchristos 	TEST_ASSERT_FALSE(keyacc_amatch(&ip4, &ipn, 0));
23256f2724eSchristos 	TEST_ASSERT_FALSE(keyacc_amatch(&ip6, NULL, 0));
23356f2724eSchristos 	TEST_ASSERT_FALSE(keyacc_amatch(&ip6, &ipn, 0));
23456f2724eSchristos }
23556f2724eSchristos 
23656f2724eSchristos void test_AddrMatch_self4(void);
test_AddrMatch_self4(void)23756f2724eSchristos void test_AddrMatch_self4(void)
23856f2724eSchristos {
23956f2724eSchristos 	sockaddr_u   ip4;
24056f2724eSchristos 	unsigned int bits;
24156f2724eSchristos 
24256f2724eSchristos 	TEST_ASSERT_TRUE(getaddr(AF_INET, "192.128.1.1", &ip4));
24356f2724eSchristos 	for (bits = 0; bits < 40; ++bits)
24456f2724eSchristos 		TEST_ASSERT_TRUE(keyacc_amatch(&ip4, &ip4, bits));
24556f2724eSchristos }
24656f2724eSchristos 
24756f2724eSchristos void test_AddrMatch_self6(void);
test_AddrMatch_self6(void)24856f2724eSchristos void test_AddrMatch_self6(void)
24956f2724eSchristos {
25056f2724eSchristos 	sockaddr_u   ip6;
25156f2724eSchristos 	unsigned int bits;
25256f2724eSchristos 
25356f2724eSchristos 	TEST_ASSERT_TRUE(getaddr(AF_INET6, "::1" , &ip6));
25456f2724eSchristos 	for (bits = 0; bits < 136; ++bits)
25556f2724eSchristos 		TEST_ASSERT_TRUE(keyacc_amatch(&ip6, &ip6, bits));
25656f2724eSchristos }
25756f2724eSchristos 
25856f2724eSchristos void test_AddrMatch_afmix(void);
test_AddrMatch_afmix(void)25956f2724eSchristos void test_AddrMatch_afmix(void)
26056f2724eSchristos {
26156f2724eSchristos 	sockaddr_u ip6, ip4;
26256f2724eSchristos 
26356f2724eSchristos 	TEST_ASSERT_TRUE(getaddr(AF_INET , "192.128.1.1", &ip4));
26456f2724eSchristos 	TEST_ASSERT_TRUE(getaddr(AF_INET6, "::1"        , &ip6));
26556f2724eSchristos 
26656f2724eSchristos 	TEST_ASSERT_FALSE(keyacc_amatch(&ip4, &ip6, 0));
26756f2724eSchristos 	TEST_ASSERT_FALSE(keyacc_amatch(&ip6, &ip4, 0));
26856f2724eSchristos }
26956f2724eSchristos 
27056f2724eSchristos void test_AddrMatch_ipv4(void);
test_AddrMatch_ipv4(void)27156f2724eSchristos void test_AddrMatch_ipv4(void)
27256f2724eSchristos {
27356f2724eSchristos 	sockaddr_u   a1, a2;
27456f2724eSchristos 	unsigned int bits;
27556f2724eSchristos 	int          want;
27656f2724eSchristos 
27756f2724eSchristos 	TEST_ASSERT_TRUE(getaddr(AF_INET, "192.128.2.1", &a1));
27856f2724eSchristos 	TEST_ASSERT_TRUE(getaddr(AF_INET, "192.128.3.1", &a2));
27956f2724eSchristos 
28056f2724eSchristos 	/* the first 23 bits are equal, so any prefix <= 23 should match */
28156f2724eSchristos 	for (bits = 0; bits < 40; ++bits) {
28256f2724eSchristos 		snprintf(msgbuf, sizeof(msgbuf),
28356f2724eSchristos 			 "keyacc_amatch(*,*,%u) wrong", bits);
28456f2724eSchristos 		want = (bits <= 23);
28556f2724eSchristos 		TEST_ASSERT_EQUAL_MESSAGE(want, keyacc_amatch(&a1, &a2, bits), msgbuf);
28656f2724eSchristos 	}
28756f2724eSchristos 
28856f2724eSchristos 	TEST_ASSERT_TRUE(getaddr(AF_INET, "192.128.2.127", &a1));
28956f2724eSchristos 	TEST_ASSERT_TRUE(getaddr(AF_INET, "192.128.2.128", &a2));
29056f2724eSchristos 
29156f2724eSchristos 	/* the first 24 bits are equal, so any prefix <= 24 should match */
29256f2724eSchristos 	for (bits = 0; bits < 40; ++bits) {
29356f2724eSchristos 		snprintf(msgbuf, sizeof(msgbuf),
29456f2724eSchristos 			 "keyacc_amatch(*,*,%u) wrong", bits);
29556f2724eSchristos 		want = (bits <= 24);
29656f2724eSchristos 		TEST_ASSERT_EQUAL_MESSAGE(want, keyacc_amatch(&a1, &a2, bits), msgbuf);
29756f2724eSchristos 	}
29856f2724eSchristos }
29956f2724eSchristos 
30056f2724eSchristos void test_AddrMatch_ipv6(void);
test_AddrMatch_ipv6(void)30156f2724eSchristos void test_AddrMatch_ipv6(void)
30256f2724eSchristos {
30356f2724eSchristos 	sockaddr_u   a1, a2;
30456f2724eSchristos 	unsigned int bits;
30556f2724eSchristos 	int          want;
30656f2724eSchristos 
30756f2724eSchristos 	TEST_ASSERT_TRUE(getaddr(AF_INET6, "FEDC:BA98:7654:3210::2:FFFF", &a1));
30856f2724eSchristos 	TEST_ASSERT_TRUE(getaddr(AF_INET6, "FEDC:BA98:7654:3210::3:FFFF", &a2));
30956f2724eSchristos 
31056f2724eSchristos 	/* the first 111 bits are equal, so any prefix <= 111 should match */
31156f2724eSchristos 	for (bits = 0; bits < 136; ++bits) {
31256f2724eSchristos 		snprintf(msgbuf, sizeof(msgbuf),
31356f2724eSchristos 			 "keyacc_amatch(*,*,%u) wrong", bits);
31456f2724eSchristos 		want = (bits <= 111);
31556f2724eSchristos 		TEST_ASSERT_EQUAL_MESSAGE(want, keyacc_amatch(&a1, &a2, bits), msgbuf);
31656f2724eSchristos 	}
31756f2724eSchristos 
31856f2724eSchristos 	TEST_ASSERT_TRUE(getaddr(AF_INET6, "FEDC:BA98:7654:3210::2:7FFF", &a1));
31956f2724eSchristos 	TEST_ASSERT_TRUE(getaddr(AF_INET6, "FEDC:BA98:7654:3210::2:8000", &a2));
32056f2724eSchristos 
32156f2724eSchristos 	/* the first 112 bits are equal, so any prefix <= 112 should match */
32256f2724eSchristos 	for (bits = 0; bits < 136; ++bits) {
32356f2724eSchristos 		snprintf(msgbuf, sizeof(msgbuf),
32456f2724eSchristos 			 "keyacc_amatch(*,*,%u) wrong", bits);
32556f2724eSchristos 		want = (bits <= 112);
32656f2724eSchristos 		TEST_ASSERT_EQUAL_MESSAGE(want, keyacc_amatch(&a1, &a2, bits), msgbuf);
32756f2724eSchristos 	}
32856f2724eSchristos }
329