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