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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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