1 #include "config.h"
2
3 #include "sntptest.h"
4 #include "networking.h"
5 #include "ntp_stdlib.h"
6 #include "unity.h"
7
8 #define CMAC "AES128CMAC"
9 #define CMAC_LENGTH 16
10
11
12 /* Hacks into the key database. */
13 extern struct key* key_ptr;
14 extern int key_cnt;
15
16
17 void PrepareAuthenticationTest(int key_id,int key_len,const char* type,const void* key_seq);
18 void setUp(void);
19 void tearDown(void);
20 void test_TooShortLength(void);
21 void test_LengthNotMultipleOfFour(void);
22 void test_TooShortExtensionFieldLength(void);
23 void test_UnauthenticatedPacketReject(void);
24 void test_CryptoNAKPacketReject(void);
25 void test_AuthenticatedPacketInvalid(void);
26 void test_AuthenticatedPacketUnknownKey(void);
27 void test_ServerVersionTooOld(void);
28 void test_ServerVersionTooNew(void);
29 void test_NonWantedMode(void);
30 void test_KoDRate(void);
31 void test_KoDDeny(void);
32 void test_RejectUnsyncedServer(void);
33 void test_RejectWrongResponseServerMode(void);
34 void test_AcceptNoSentPacketBroadcastMode(void);
35 void test_CorrectUnauthenticatedPacket(void);
36 void test_CorrectAuthenticatedPacketMD5(void);
37 void test_CorrectAuthenticatedPacketSHAKE128(void);
38 void test_CorrectAuthenticatedPacketSHA1(void);
39 void test_CorrectAuthenticatedPacketCMAC(void);
40
41 /* [Bug 2998] There are some issues whith the definition of 'struct pkt'
42 * when AUTOKEY is undefined -- the formal struct is too small to hold
43 * all the extension fields that are going to be tested. We have to make
44 * sure we have the extra bytes, or the test yields undefined results due
45 * to buffer overrun.
46 */
47 #ifndef AUTOKEY
48 # define EXTRA_BUFSIZE 256
49 #else
50 # define EXTRA_BUFSIZE 0
51 #endif
52
53 union tpkt {
54 struct pkt p;
55 u_char b[sizeof(struct pkt) + EXTRA_BUFSIZE];
56 };
57
58 static union tpkt testpkt;
59 static union tpkt testspkt;
60 static sockaddr_u testsock;
61 bool restoreKeyDb;
62
63
64 void
PrepareAuthenticationTest(int key_id,int key_len,const char * type,const void * key_seq)65 PrepareAuthenticationTest(
66 int key_id,
67 int key_len,
68 const char * type,
69 const void * key_seq
70 )
71 {
72 char str[25];
73
74 snprintf(str, sizeof(str), "%d", key_id);
75 ActivateOption("-a", str);
76
77 key_cnt = 1;
78 if (NULL == key_ptr) {
79 key_ptr = emalloc(sizeof(*key_ptr));
80 }
81 key_ptr->next = NULL;
82 key_ptr->key_id = key_id;
83 key_ptr->key_len = key_len;
84 strncpy(key_ptr->typen, type, sizeof(key_ptr->typen));
85
86 TEST_ASSERT_TRUE(key_len < sizeof(key_ptr->key_seq));
87
88 memcpy(key_ptr->key_seq, key_seq,
89 min(key_len, sizeof(key_ptr->key_seq)));
90 restoreKeyDb = true;
91 }
92
93
94 void
setUp(void)95 setUp(void)
96 {
97
98 sntptest();
99 restoreKeyDb = false;
100
101 /* Initialize the test packet and socket,
102 * so they contain at least some valid data.
103 */
104 testpkt.p.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING, NTP_VERSION,
105 MODE_SERVER);
106 testpkt.p.stratum = STRATUM_REFCLOCK;
107 memcpy(&testpkt.p.refid, "GPS\0", 4);
108
109 /* Set the origin timestamp of the received packet to the
110 * same value as the transmit timestamp of the sent packet.
111 */
112 l_fp tmp;
113 tmp.l_ui = 1000UL;
114 tmp.l_uf = 0UL;
115
116 HTONL_FP(&tmp, &testpkt.p.org);
117 HTONL_FP(&tmp, &testspkt.p.xmt);
118 }
119
120
121 void
tearDown(void)122 tearDown(void)
123 {
124 if (restoreKeyDb) {
125 key_cnt = 0;
126 free(key_ptr);
127 key_ptr = NULL;
128 }
129
130 sntptest_destroy(); /* only on the final test!! if counter == 0 etc... */
131 }
132
133
134 void
test_TooShortLength(void)135 test_TooShortLength(void)
136 {
137 TEST_ASSERT_EQUAL(PACKET_UNUSEABLE,
138 process_pkt(&testpkt.p, &testsock, LEN_PKT_NOMAC - 1,
139 MODE_SERVER, &testspkt.p, "UnitTest"));
140 TEST_ASSERT_EQUAL(PACKET_UNUSEABLE,
141 process_pkt(&testpkt.p, &testsock, LEN_PKT_NOMAC - 1,
142 MODE_BROADCAST, &testspkt.p, "UnitTest"));
143 }
144
145
146 void
test_LengthNotMultipleOfFour(void)147 test_LengthNotMultipleOfFour(void)
148 {
149 TEST_ASSERT_EQUAL(PACKET_UNUSEABLE,
150 process_pkt(&testpkt.p, &testsock, LEN_PKT_NOMAC + 6,
151 MODE_SERVER, &testspkt.p, "UnitTest"));
152 TEST_ASSERT_EQUAL(PACKET_UNUSEABLE,
153 process_pkt(&testpkt.p, &testsock, LEN_PKT_NOMAC + 3,
154 MODE_BROADCAST, &testspkt.p, "UnitTest"));
155 }
156
157
158 void
test_TooShortExtensionFieldLength(void)159 test_TooShortExtensionFieldLength(void)
160 {
161 /* [Bug 2998] We have to get around the formal specification of
162 * the extension field if AUTOKEY is undefined. (At least CLANG
163 * issues a warning in this case. It's just a warning, but
164 * still...
165 */
166 uint32_t * pe = testpkt.p.exten + 7;
167
168 /* The lower 16-bits are the length of the extension field.
169 * This lengths must be multiples of 4 bytes, which gives
170 * a minimum of 4 byte extension field length.
171 */
172 *pe = htonl(3); /* 3 bytes is too short. */
173
174 /* We send in a pkt_len of header size + 4 byte extension
175 * header + 24 byte MAC, this prevents the length error to
176 * be caught at an earlier stage
177 */
178 int pkt_len = LEN_PKT_NOMAC + 4 + 24;
179
180 TEST_ASSERT_EQUAL(PACKET_UNUSEABLE,
181 process_pkt(&testpkt.p, &testsock, pkt_len,
182 MODE_SERVER, &testspkt.p, "UnitTest"));
183 }
184
185
186 void
test_UnauthenticatedPacketReject(void)187 test_UnauthenticatedPacketReject(void)
188 {
189 /* Activate authentication option */
190 ActivateOption("-a", "123");
191 TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
192
193 int pkt_len = LEN_PKT_NOMAC;
194
195 /* We demand authentication, but no MAC header is present. */
196 TEST_ASSERT_EQUAL(SERVER_AUTH_FAIL,
197 process_pkt(&testpkt.p, &testsock, pkt_len,
198 MODE_SERVER, &testspkt.p, "UnitTest"));
199 }
200
201
202 void
test_CryptoNAKPacketReject(void)203 test_CryptoNAKPacketReject(void)
204 {
205 /* Activate authentication option */
206 ActivateOption("-a", "123");
207 TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
208
209 int pkt_len = LEN_PKT_NOMAC + 4; /* + 4 byte MAC = Crypto-NAK */
210
211 TEST_ASSERT_EQUAL(SERVER_AUTH_FAIL,
212 process_pkt(&testpkt.p, &testsock, pkt_len,
213 MODE_SERVER, &testspkt.p, "UnitTest"));
214 }
215
216
217 void
test_AuthenticatedPacketInvalid(void)218 test_AuthenticatedPacketInvalid(void)
219 {
220 #ifdef OPENSSL
221 size_t pkt_len = LEN_PKT_NOMAC;
222 size_t mac_len;
223
224 /* Activate authentication option */
225 PrepareAuthenticationTest(50, 9, "SHAKE128", "123456789");
226 TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
227
228 /* Prepare the packet. */
229 testpkt.p.exten[0] = htonl(50);
230 mac_len = make_mac(&testpkt.p, pkt_len, key_ptr,
231 &testpkt.p.exten[1], MAX_MDG_LEN);
232
233 pkt_len += KEY_MAC_LEN + mac_len;
234
235 /* Now, alter the MAC so it becomes invalid. */
236 testpkt.p.exten[1] += 1;
237
238 TEST_ASSERT_EQUAL(SERVER_AUTH_FAIL,
239 process_pkt(&testpkt.p, &testsock, pkt_len,
240 MODE_SERVER, &testspkt.p, "UnitTest"));
241
242 #else
243
244 TEST_IGNORE_MESSAGE("OpenSSL not enabled, skipping...");
245
246 #endif
247 }
248
249
250 void
test_AuthenticatedPacketUnknownKey(void)251 test_AuthenticatedPacketUnknownKey(void)
252 {
253 #ifdef OPENSSL
254 size_t pkt_len = LEN_PKT_NOMAC;
255 size_t mac_len;
256
257 /* Activate authentication option */
258 PrepareAuthenticationTest(30, 9, "SHAKE128", "123456789");
259 TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
260
261 /* Prepare the packet. Note that the Key-ID expected is 30, but
262 * the packet has a key id of 50.
263 */
264 testpkt.p.exten[0] = htonl(50);
265 mac_len = make_mac(&testpkt.p, pkt_len, key_ptr,
266 &testpkt.p.exten[1], MAX_MDG_LEN);
267 pkt_len += KEY_MAC_LEN + mac_len;
268
269 TEST_ASSERT_EQUAL(SERVER_AUTH_FAIL,
270 process_pkt(&testpkt.p, &testsock, pkt_len,
271 MODE_SERVER, &testspkt.p, "UnitTest"));
272
273 #else
274
275 TEST_IGNORE_MESSAGE("OpenSSL not enabled, skipping...");
276
277 #endif
278 }
279
280
281 void
test_ServerVersionTooOld(void)282 test_ServerVersionTooOld(void)
283 {
284 TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
285
286 testpkt.p.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
287 NTP_OLDVERSION - 1,
288 MODE_CLIENT);
289 TEST_ASSERT_TRUE(PKT_VERSION(testpkt.p.li_vn_mode) < NTP_OLDVERSION);
290
291 int pkt_len = LEN_PKT_NOMAC;
292
293 TEST_ASSERT_EQUAL(SERVER_UNUSEABLE,
294 process_pkt(&testpkt.p, &testsock, pkt_len,
295 MODE_SERVER, &testspkt.p, "UnitTest"));
296 }
297
298
299 void
test_ServerVersionTooNew(void)300 test_ServerVersionTooNew(void)
301 {
302 TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
303
304 testpkt.p.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
305 NTP_VERSION + 1,
306 MODE_CLIENT);
307 TEST_ASSERT_TRUE(PKT_VERSION(testpkt.p.li_vn_mode) > NTP_VERSION);
308
309 int pkt_len = LEN_PKT_NOMAC;
310
311 TEST_ASSERT_EQUAL(SERVER_UNUSEABLE,
312 process_pkt(&testpkt.p, &testsock, pkt_len,
313 MODE_SERVER, &testspkt.p, "UnitTest"));
314 }
315
316
317 void
test_NonWantedMode(void)318 test_NonWantedMode(void)
319 {
320 TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
321
322 testpkt.p.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
323 NTP_VERSION,
324 MODE_CLIENT);
325
326 /* The packet has a mode of MODE_CLIENT, but process_pkt expects
327 * MODE_SERVER
328 */
329 TEST_ASSERT_EQUAL(SERVER_UNUSEABLE,
330 process_pkt(&testpkt.p, &testsock, LEN_PKT_NOMAC,
331 MODE_SERVER, &testspkt.p, "UnitTest"));
332 }
333
334
335 /* Tests bug 1597 */
336 void
test_KoDRate(void)337 test_KoDRate(void)
338 {
339 TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
340
341 testpkt.p.stratum = STRATUM_PKT_UNSPEC;
342 memcpy(&testpkt.p.refid, "RATE", 4);
343
344 TEST_ASSERT_EQUAL(KOD_RATE,
345 process_pkt(&testpkt.p, &testsock, LEN_PKT_NOMAC,
346 MODE_SERVER, &testspkt.p, "UnitTest"));
347 }
348
349
350 void
test_KoDDeny(void)351 test_KoDDeny(void)
352 {
353 TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
354
355 testpkt.p.stratum = STRATUM_PKT_UNSPEC;
356 memcpy(&testpkt.p.refid, "DENY", 4);
357
358 TEST_ASSERT_EQUAL(KOD_DEMOBILIZE,
359 process_pkt(&testpkt.p, &testsock, LEN_PKT_NOMAC,
360 MODE_SERVER, &testspkt.p, "UnitTest"));
361 }
362
363
364 void
test_RejectUnsyncedServer(void)365 test_RejectUnsyncedServer(void)
366 {
367 TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
368
369 testpkt.p.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOTINSYNC,
370 NTP_VERSION,
371 MODE_SERVER);
372
373 TEST_ASSERT_EQUAL(SERVER_UNUSEABLE,
374 process_pkt(&testpkt.p, &testsock, LEN_PKT_NOMAC,
375 MODE_SERVER, &testspkt.p, "UnitTest"));
376 }
377
378
379 void
test_RejectWrongResponseServerMode(void)380 test_RejectWrongResponseServerMode(void)
381 {
382 TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
383
384 l_fp tmp;
385 tmp.l_ui = 1000UL;
386 tmp.l_uf = 0UL;
387 HTONL_FP(&tmp, &testpkt.p.org);
388
389 tmp.l_ui = 2000UL;
390 tmp.l_uf = 0UL;
391 HTONL_FP(&tmp, &testspkt.p.xmt);
392
393 TEST_ASSERT_EQUAL(PACKET_UNUSEABLE,
394 process_pkt(&testpkt.p, &testsock, LEN_PKT_NOMAC,
395 MODE_SERVER, &testspkt.p, "UnitTest"));
396 }
397
398
399 void
test_AcceptNoSentPacketBroadcastMode(void)400 test_AcceptNoSentPacketBroadcastMode(void)
401 {
402 TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
403
404 testpkt.p.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
405 NTP_VERSION,
406 MODE_BROADCAST);
407
408 TEST_ASSERT_EQUAL(LEN_PKT_NOMAC,
409 process_pkt(&testpkt.p, &testsock, LEN_PKT_NOMAC,
410 MODE_BROADCAST, NULL, "UnitTest"));
411 }
412
413
414 void
test_CorrectUnauthenticatedPacket(void)415 test_CorrectUnauthenticatedPacket(void)
416 {
417 TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
418
419 TEST_ASSERT_EQUAL(LEN_PKT_NOMAC,
420 process_pkt(&testpkt.p, &testsock, LEN_PKT_NOMAC,
421 MODE_SERVER, &testspkt.p, "UnitTest"));
422 }
423
424
425 void
test_CorrectAuthenticatedPacketMD5(void)426 test_CorrectAuthenticatedPacketMD5(void)
427 {
428 #ifdef OPENSSL
429
430 keyid_t k_id = 10;
431 int pkt_len = LEN_PKT_NOMAC;
432 int mac_len;
433
434 PrepareAuthenticationTest(k_id, 15, "MD5", "123456789abcdef");
435 TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
436
437 /* Prepare the packet. */
438 testpkt.p.exten[0] = htonl(k_id);
439 mac_len = make_mac(&testpkt.p, pkt_len, key_ptr,
440 &testpkt.p.exten[1], MAX_MDG_LEN);
441
442 /* TODO: Should not expect failure if non-FIPS OpenSSL */
443 TEST_EXPECT_FAIL_MESSAGE("FIPS OpenSSL bars MD5");
444
445 pkt_len += KEY_MAC_LEN + mac_len;
446
447 TEST_ASSERT_EQUAL(pkt_len,
448 process_pkt(&testpkt.p, &testsock, pkt_len,
449 MODE_SERVER, &testspkt.p, "UnitTest"));
450
451 #else
452
453 TEST_IGNORE_MESSAGE("OpenSSL not enabled, skipping...");
454
455 #endif
456 }
457
458
459 void
test_CorrectAuthenticatedPacketSHAKE128(void)460 test_CorrectAuthenticatedPacketSHAKE128(void)
461 {
462 #ifdef OPENSSL
463
464 keyid_t k_id = 10;
465 int pkt_len = LEN_PKT_NOMAC;
466 int mac_len;
467
468 PrepareAuthenticationTest(k_id, 15, "SHAKE128", "123456789abcdef");
469 TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
470
471 /* Prepare the packet. */
472 testpkt.p.exten[0] = htonl(k_id);
473 mac_len = make_mac(&testpkt.p, pkt_len, key_ptr, &testpkt.p.exten[1],
474 SHAKE128_LENGTH);
475
476 pkt_len += KEY_MAC_LEN + mac_len;
477
478 TEST_ASSERT_EQUAL(pkt_len,
479 process_pkt(&testpkt.p, &testsock, pkt_len,
480 MODE_SERVER, &testspkt.p, "UnitTest"));
481
482 #else
483
484 TEST_IGNORE_MESSAGE("OpenSSL not enabled, skipping...");
485
486 #endif
487 }
488
489
490 void
test_CorrectAuthenticatedPacketSHA1(void)491 test_CorrectAuthenticatedPacketSHA1(void)
492 {
493 #ifdef OPENSSL
494
495 keyid_t k_id = 20;
496 int pkt_len = LEN_PKT_NOMAC;
497 int mac_len;
498
499 PrepareAuthenticationTest(k_id, 15, "SHA1", "abcdefghijklmno");
500 TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
501
502 /* Prepare the packet. */
503 testpkt.p.exten[0] = htonl(k_id);
504 mac_len = make_mac(&testpkt.p, pkt_len, key_ptr, &testpkt.p.exten[1],
505 SHA1_LENGTH);
506
507 pkt_len += KEY_MAC_LEN + mac_len;
508
509 TEST_ASSERT_EQUAL(pkt_len,
510 process_pkt(&testpkt.p, &testsock, pkt_len,
511 MODE_SERVER, &testspkt.p, "UnitTest"));
512
513 #else
514
515 TEST_IGNORE_MESSAGE("OpenSSL not enabled, skipping...");
516
517 #endif
518 }
519
520
521 void
test_CorrectAuthenticatedPacketCMAC(void)522 test_CorrectAuthenticatedPacketCMAC(void)
523 {
524 #if defined(OPENSSL) && defined(ENABLE_CMAC)
525
526 PrepareAuthenticationTest(30, CMAC_LENGTH, CMAC, "abcdefghijklmnop");
527 TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
528
529 int pkt_len = LEN_PKT_NOMAC;
530
531 /* Prepare the packet. */
532 testpkt.p.exten[0] = htonl(30);
533 int mac_len = make_mac(&testpkt.p, pkt_len, key_ptr,
534 &testpkt.p.exten[1], MAX_MAC_LEN);
535
536 pkt_len += 4 + mac_len;
537
538 TEST_ASSERT_EQUAL(pkt_len,
539 process_pkt(&testpkt.p, &testsock, pkt_len,
540 MODE_SERVER, &testspkt.p, "UnitTest"));
541
542 #else
543
544 TEST_IGNORE_MESSAGE("CMAC not enabled, skipping...");
545
546 #endif /* OPENSSL */
547 }
548
549