authkeys.c revision 1.1.1.9 1 1.1.1.9 christos /* $NetBSD: authkeys.c,v 1.1.1.9 2020/05/25 20:40:16 christos Exp $ */
2 1.1.1.9 christos
3 1.1 christos /* This file contains test for both libntp/authkeys.c and libntp/authusekey.c */
4 1.1 christos
5 1.1 christos #include "config.h"
6 1.1 christos
7 1.1 christos #include "ntp.h"
8 1.1 christos #include "ntp_stdlib.h"
9 1.1 christos #include "ntp_calendar.h"
10 1.1 christos
11 1.1 christos #include "unity.h"
12 1.1 christos
13 1.1 christos #ifdef OPENSSL
14 1.1 christos # include "openssl/err.h"
15 1.1 christos # include "openssl/rand.h"
16 1.1 christos # include "openssl/evp.h"
17 1.1 christos #endif
18 1.1.1.6 christos #include <limits.h>
19 1.1 christos
20 1.1 christos u_long current_time = 4;
21 1.1 christos int counter = 0;
22 1.1 christos
23 1.1.1.3 christos void setUp(void);
24 1.1.1.3 christos void tearDown(void);
25 1.1.1.3 christos void AddTrustedKey(keyid_t keyno);
26 1.1.1.7 christos void AddUntrustedKey(keyid_t keyno);
27 1.1 christos
28 1.1.1.3 christos
29 1.1.1.3 christos void
30 1.1.1.3 christos setUp(void)
31 1.1.1.7 christos {
32 1.1.1.3 christos if (counter == 0) {
33 1.1.1.3 christos counter++;
34 1.1.1.3 christos init_auth(); // causes segfault if called more than once
35 1.1 christos }
36 1.1.1.3 christos /*
37 1.1 christos * init_auth() is called by tests_main.cpp earlier. It
38 1.1 christos * does not initialize global variables like
39 1.1 christos * authnumkeys, so let's reset them to zero here.
40 1.1 christos */
41 1.1 christos authnumkeys = 0;
42 1.1 christos
43 1.1 christos /*
44 1.1 christos * Especially, empty the key cache!
45 1.1 christos */
46 1.1 christos cache_keyid = 0;
47 1.1 christos cache_type = 0;
48 1.1 christos cache_flags = 0;
49 1.1 christos cache_secret = NULL;
50 1.1 christos cache_secretsize = 0;
51 1.1 christos }
52 1.1 christos
53 1.1.1.3 christos void
54 1.1.1.3 christos tearDown(void)
55 1.1 christos {
56 1.1.1.7 christos /*NOP*/
57 1.1.1.3 christos }
58 1.1 christos
59 1.1.1.7 christos
60 1.1 christos static const int KEYTYPE = KEY_TYPE_MD5;
61 1.1.1.7 christos static char msgbuf[128];
62 1.1 christos
63 1.1.1.3 christos void
64 1.1.1.4 christos AddTrustedKey(keyid_t keyno)
65 1.1.1.4 christos {
66 1.1 christos /*
67 1.1 christos * We need to add a MD5-key in addition to setting the
68 1.1 christos * trust, because authhavekey() requires type != 0.
69 1.1 christos */
70 1.1.1.6 christos MD5auth_setkey(keyno, KEYTYPE, NULL, 0, NULL);
71 1.1 christos
72 1.1 christos authtrust(keyno, TRUE);
73 1.1 christos }
74 1.1 christos
75 1.1.1.3 christos void
76 1.1.1.4 christos AddUntrustedKey(keyid_t keyno)
77 1.1.1.4 christos {
78 1.1 christos authtrust(keyno, FALSE);
79 1.1 christos }
80 1.1 christos
81 1.1.1.7 christos void test_AddTrustedKeys(void);
82 1.1.1.7 christos void test_AddTrustedKeys(void)
83 1.1.1.4 christos {
84 1.1 christos const keyid_t KEYNO1 = 5;
85 1.1 christos const keyid_t KEYNO2 = 8;
86 1.1 christos
87 1.1 christos AddTrustedKey(KEYNO1);
88 1.1 christos AddTrustedKey(KEYNO2);
89 1.1 christos
90 1.1 christos TEST_ASSERT_TRUE(authistrusted(KEYNO1));
91 1.1 christos TEST_ASSERT_TRUE(authistrusted(KEYNO2));
92 1.1 christos }
93 1.1 christos
94 1.1.1.7 christos void test_AddUntrustedKey(void);
95 1.1.1.7 christos void test_AddUntrustedKey(void)
96 1.1.1.4 christos {
97 1.1 christos const keyid_t KEYNO = 3;
98 1.1.1.7 christos
99 1.1 christos AddUntrustedKey(KEYNO);
100 1.1 christos
101 1.1 christos TEST_ASSERT_FALSE(authistrusted(KEYNO));
102 1.1 christos }
103 1.1 christos
104 1.1.1.7 christos void test_HaveKeyCorrect(void);
105 1.1.1.7 christos void test_HaveKeyCorrect(void)
106 1.1.1.4 christos {
107 1.1 christos const keyid_t KEYNO = 3;
108 1.1 christos
109 1.1 christos AddTrustedKey(KEYNO);
110 1.1 christos
111 1.1 christos TEST_ASSERT_TRUE(auth_havekey(KEYNO));
112 1.1 christos TEST_ASSERT_TRUE(authhavekey(KEYNO));
113 1.1 christos }
114 1.1 christos
115 1.1.1.7 christos void test_HaveKeyIncorrect(void);
116 1.1.1.7 christos void test_HaveKeyIncorrect(void)
117 1.1.1.4 christos {
118 1.1 christos const keyid_t KEYNO = 2;
119 1.1 christos
120 1.1 christos TEST_ASSERT_FALSE(auth_havekey(KEYNO));
121 1.1 christos TEST_ASSERT_FALSE(authhavekey(KEYNO));
122 1.1 christos }
123 1.1 christos
124 1.1.1.7 christos void test_AddWithAuthUseKey(void);
125 1.1.1.7 christos void test_AddWithAuthUseKey(void)
126 1.1.1.4 christos {
127 1.1 christos const keyid_t KEYNO = 5;
128 1.1 christos const char* KEY = "52a";
129 1.1 christos
130 1.1.1.4 christos TEST_ASSERT_TRUE(authusekey(KEYNO, KEYTYPE, (const u_char*)KEY));
131 1.1 christos }
132 1.1 christos
133 1.1.1.7 christos void test_EmptyKey(void);
134 1.1.1.7 christos void test_EmptyKey(void)
135 1.1.1.4 christos {
136 1.1 christos const keyid_t KEYNO = 3;
137 1.1 christos const char* KEY = "";
138 1.1 christos
139 1.1.1.4 christos TEST_ASSERT_FALSE(authusekey(KEYNO, KEYTYPE, (const u_char*)KEY));
140 1.1 christos }
141 1.1.1.6 christos
142 1.1.1.6 christos /* test the implementation of 'auth_log2' -- use a local copy of the code */
143 1.1.1.6 christos
144 1.1.1.6 christos static u_short
145 1.1.1.6 christos auth_log2(
146 1.1.1.6 christos size_t x)
147 1.1.1.6 christos {
148 1.1.1.6 christos int s;
149 1.1.1.6 christos int r = 0;
150 1.1.1.6 christos size_t m = ~(size_t)0;
151 1.1.1.6 christos
152 1.1.1.6 christos for (s = sizeof(size_t) / 2 * CHAR_BIT; s != 0; s >>= 1) {
153 1.1.1.6 christos m <<= s;
154 1.1.1.6 christos if (x & m)
155 1.1.1.6 christos r += s;
156 1.1.1.6 christos else
157 1.1.1.6 christos x <<= s;
158 1.1.1.6 christos }
159 1.1.1.6 christos return (u_short)r;
160 1.1.1.6 christos }
161 1.1.1.6 christos
162 1.1.1.7 christos void test_auth_log2(void);
163 1.1.1.7 christos void test_auth_log2(void)
164 1.1.1.6 christos {
165 1.1.1.6 christos int l2;
166 1.1.1.6 christos size_t tv;
167 1.1.1.7 christos
168 1.1.1.6 christos TEST_ASSERT_EQUAL_INT(0, auth_log2(0));
169 1.1.1.6 christos TEST_ASSERT_EQUAL_INT(0, auth_log2(1));
170 1.1.1.6 christos for (l2 = 1; l2 < sizeof(size_t)*CHAR_BIT; ++l2) {
171 1.1.1.6 christos tv = (size_t)1 << l2;
172 1.1.1.6 christos TEST_ASSERT_EQUAL_INT(l2, auth_log2( tv ));
173 1.1.1.6 christos TEST_ASSERT_EQUAL_INT(l2, auth_log2( tv + 1 ));
174 1.1.1.6 christos TEST_ASSERT_EQUAL_INT(l2, auth_log2(2*tv - 1));
175 1.1.1.6 christos }
176 1.1.1.6 christos }
177 1.1.1.7 christos
178 1.1.1.7 christos /* Converting a string to a host address. Here we use 'getaddrinfo()' in
179 1.1.1.7 christos * an independent implementation to avoid cross-reactions with the
180 1.1.1.7 christos * object under test. 'inet_pton' is too dangerous to handle it
181 1.1.1.7 christos * properly, and ultimate performance is *not* the goal here.
182 1.1.1.7 christos */
183 1.1.1.7 christos static int/*BOOL*/
184 1.1.1.7 christos getaddr(
185 1.1.1.7 christos int af,
186 1.1.1.7 christos const char *astr,
187 1.1.1.7 christos sockaddr_u * addr)
188 1.1.1.7 christos {
189 1.1.1.7 christos struct addrinfo hint;
190 1.1.1.7 christos struct addrinfo *ares;
191 1.1.1.7 christos
192 1.1.1.7 christos memset(&hint, 0, sizeof(hint));
193 1.1.1.7 christos hint.ai_flags = AI_NUMERICHOST;
194 1.1.1.7 christos hint.ai_family = af;
195 1.1.1.7 christos if (getaddrinfo(astr, NULL, &hint, &ares))
196 1.1.1.7 christos return FALSE;
197 1.1.1.7 christos if (ares->ai_addrlen > sizeof(*addr))
198 1.1.1.7 christos memcpy(addr, ares->ai_addr, sizeof(*addr));
199 1.1.1.7 christos else
200 1.1.1.7 christos memcpy(addr, ares->ai_addr, ares->ai_addrlen);
201 1.1.1.7 christos freeaddrinfo(ares);
202 1.1.1.7 christos return TRUE;
203 1.1.1.7 christos }
204 1.1.1.7 christos
205 1.1.1.7 christos void test_AddrMatch_anull(void);
206 1.1.1.7 christos void test_AddrMatch_anull(void)
207 1.1.1.7 christos {
208 1.1.1.7 christos /* Check the not-an-address logic with a prefix/check length of
209 1.1.1.7 christos * zero bits. Any compare with a NULL or AF_UNSPEC address
210 1.1.1.7 christos * returns inequality (aka FALSE).
211 1.1.1.7 christos */
212 1.1.1.7 christos sockaddr_u ip4, ip6, ipn;
213 1.1.1.7 christos
214 1.1.1.7 christos memset(&ipn, 0, sizeof(ipn));
215 1.1.1.7 christos AF(&ipn) = AF_UNSPEC;
216 1.1.1.7 christos
217 1.1.1.7 christos TEST_ASSERT_TRUE(getaddr(AF_INET , "192.128.1.1", &ip4));
218 1.1.1.7 christos TEST_ASSERT_TRUE(getaddr(AF_INET6, "::1" , &ip6));
219 1.1.1.7 christos
220 1.1.1.7 christos TEST_ASSERT_FALSE(keyacc_amatch(NULL, NULL, 0));
221 1.1.1.7 christos TEST_ASSERT_FALSE(keyacc_amatch(NULL, &ipn, 0));
222 1.1.1.7 christos TEST_ASSERT_FALSE(keyacc_amatch(NULL, &ip4, 0));
223 1.1.1.7 christos TEST_ASSERT_FALSE(keyacc_amatch(NULL, &ip6, 0));
224 1.1.1.7 christos
225 1.1.1.7 christos TEST_ASSERT_FALSE(keyacc_amatch(&ipn, NULL, 0));
226 1.1.1.7 christos TEST_ASSERT_FALSE(keyacc_amatch(&ipn, &ipn, 0));
227 1.1.1.7 christos TEST_ASSERT_FALSE(keyacc_amatch(&ipn, &ip4, 0));
228 1.1.1.7 christos TEST_ASSERT_FALSE(keyacc_amatch(&ipn, &ip6, 0));
229 1.1.1.7 christos
230 1.1.1.7 christos TEST_ASSERT_FALSE(keyacc_amatch(&ip4, NULL, 0));
231 1.1.1.7 christos TEST_ASSERT_FALSE(keyacc_amatch(&ip4, &ipn, 0));
232 1.1.1.7 christos TEST_ASSERT_FALSE(keyacc_amatch(&ip6, NULL, 0));
233 1.1.1.7 christos TEST_ASSERT_FALSE(keyacc_amatch(&ip6, &ipn, 0));
234 1.1.1.7 christos }
235 1.1.1.7 christos
236 1.1.1.7 christos void test_AddrMatch_self4(void);
237 1.1.1.7 christos void test_AddrMatch_self4(void)
238 1.1.1.7 christos {
239 1.1.1.7 christos sockaddr_u ip4;
240 1.1.1.7 christos unsigned int bits;
241 1.1.1.7 christos
242 1.1.1.7 christos TEST_ASSERT_TRUE(getaddr(AF_INET, "192.128.1.1", &ip4));
243 1.1.1.7 christos for (bits = 0; bits < 40; ++bits)
244 1.1.1.7 christos TEST_ASSERT_TRUE(keyacc_amatch(&ip4, &ip4, bits));
245 1.1.1.7 christos }
246 1.1.1.7 christos
247 1.1.1.7 christos void test_AddrMatch_self6(void);
248 1.1.1.7 christos void test_AddrMatch_self6(void)
249 1.1.1.7 christos {
250 1.1.1.7 christos sockaddr_u ip6;
251 1.1.1.7 christos unsigned int bits;
252 1.1.1.7 christos
253 1.1.1.7 christos TEST_ASSERT_TRUE(getaddr(AF_INET6, "::1" , &ip6));
254 1.1.1.7 christos for (bits = 0; bits < 136; ++bits)
255 1.1.1.7 christos TEST_ASSERT_TRUE(keyacc_amatch(&ip6, &ip6, bits));
256 1.1.1.7 christos }
257 1.1.1.7 christos
258 1.1.1.7 christos void test_AddrMatch_afmix(void);
259 1.1.1.7 christos void test_AddrMatch_afmix(void)
260 1.1.1.7 christos {
261 1.1.1.7 christos sockaddr_u ip6, ip4;
262 1.1.1.7 christos
263 1.1.1.7 christos TEST_ASSERT_TRUE(getaddr(AF_INET , "192.128.1.1", &ip4));
264 1.1.1.7 christos TEST_ASSERT_TRUE(getaddr(AF_INET6, "::1" , &ip6));
265 1.1.1.7 christos
266 1.1.1.7 christos TEST_ASSERT_FALSE(keyacc_amatch(&ip4, &ip6, 0));
267 1.1.1.7 christos TEST_ASSERT_FALSE(keyacc_amatch(&ip6, &ip4, 0));
268 1.1.1.7 christos }
269 1.1.1.7 christos
270 1.1.1.7 christos void test_AddrMatch_ipv4(void);
271 1.1.1.7 christos void test_AddrMatch_ipv4(void)
272 1.1.1.7 christos {
273 1.1.1.7 christos sockaddr_u a1, a2;
274 1.1.1.7 christos unsigned int bits;
275 1.1.1.7 christos int want;
276 1.1.1.7 christos
277 1.1.1.7 christos TEST_ASSERT_TRUE(getaddr(AF_INET, "192.128.2.1", &a1));
278 1.1.1.7 christos TEST_ASSERT_TRUE(getaddr(AF_INET, "192.128.3.1", &a2));
279 1.1.1.7 christos
280 1.1.1.7 christos /* the first 23 bits are equal, so any prefix <= 23 should match */
281 1.1.1.7 christos for (bits = 0; bits < 40; ++bits) {
282 1.1.1.7 christos snprintf(msgbuf, sizeof(msgbuf),
283 1.1.1.7 christos "keyacc_amatch(*,*,%u) wrong", bits);
284 1.1.1.7 christos want = (bits <= 23);
285 1.1.1.7 christos TEST_ASSERT_EQUAL_MESSAGE(want, keyacc_amatch(&a1, &a2, bits), msgbuf);
286 1.1.1.7 christos }
287 1.1.1.7 christos
288 1.1.1.7 christos TEST_ASSERT_TRUE(getaddr(AF_INET, "192.128.2.127", &a1));
289 1.1.1.7 christos TEST_ASSERT_TRUE(getaddr(AF_INET, "192.128.2.128", &a2));
290 1.1.1.7 christos
291 1.1.1.7 christos /* the first 24 bits are equal, so any prefix <= 24 should match */
292 1.1.1.7 christos for (bits = 0; bits < 40; ++bits) {
293 1.1.1.7 christos snprintf(msgbuf, sizeof(msgbuf),
294 1.1.1.7 christos "keyacc_amatch(*,*,%u) wrong", bits);
295 1.1.1.7 christos want = (bits <= 24);
296 1.1.1.7 christos TEST_ASSERT_EQUAL_MESSAGE(want, keyacc_amatch(&a1, &a2, bits), msgbuf);
297 1.1.1.7 christos }
298 1.1.1.7 christos }
299 1.1.1.7 christos
300 1.1.1.7 christos void test_AddrMatch_ipv6(void);
301 1.1.1.7 christos void test_AddrMatch_ipv6(void)
302 1.1.1.7 christos {
303 1.1.1.7 christos sockaddr_u a1, a2;
304 1.1.1.7 christos unsigned int bits;
305 1.1.1.7 christos int want;
306 1.1.1.7 christos
307 1.1.1.7 christos TEST_ASSERT_TRUE(getaddr(AF_INET6, "FEDC:BA98:7654:3210::2:FFFF", &a1));
308 1.1.1.7 christos TEST_ASSERT_TRUE(getaddr(AF_INET6, "FEDC:BA98:7654:3210::3:FFFF", &a2));
309 1.1.1.7 christos
310 1.1.1.7 christos /* the first 111 bits are equal, so any prefix <= 111 should match */
311 1.1.1.7 christos for (bits = 0; bits < 136; ++bits) {
312 1.1.1.7 christos snprintf(msgbuf, sizeof(msgbuf),
313 1.1.1.7 christos "keyacc_amatch(*,*,%u) wrong", bits);
314 1.1.1.7 christos want = (bits <= 111);
315 1.1.1.7 christos TEST_ASSERT_EQUAL_MESSAGE(want, keyacc_amatch(&a1, &a2, bits), msgbuf);
316 1.1.1.7 christos }
317 1.1.1.7 christos
318 1.1.1.7 christos TEST_ASSERT_TRUE(getaddr(AF_INET6, "FEDC:BA98:7654:3210::2:7FFF", &a1));
319 1.1.1.7 christos TEST_ASSERT_TRUE(getaddr(AF_INET6, "FEDC:BA98:7654:3210::2:8000", &a2));
320 1.1.1.7 christos
321 1.1.1.7 christos /* the first 112 bits are equal, so any prefix <= 112 should match */
322 1.1.1.7 christos for (bits = 0; bits < 136; ++bits) {
323 1.1.1.7 christos snprintf(msgbuf, sizeof(msgbuf),
324 1.1.1.7 christos "keyacc_amatch(*,*,%u) wrong", bits);
325 1.1.1.7 christos want = (bits <= 112);
326 1.1.1.7 christos TEST_ASSERT_EQUAL_MESSAGE(want, keyacc_amatch(&a1, &a2, bits), msgbuf);
327 1.1.1.7 christos }
328 1.1.1.7 christos }
329