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