Home | History | Annotate | Line # | Download | only in libntp
authkeys.c revision 1.3
      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 
     20 u_long current_time = 4;
     21 int counter = 0;
     22 
     23 void setUp(void);
     24 void tearDown(void);
     25 void AddTrustedKey(keyid_t keyno);
     26 void AddUntrustedKey(keyid_t keyno);
     27 
     28 
     29 void
     30 setUp(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 
     53 void
     54 tearDown(void)
     55 {
     56 	/*NOP*/
     57 }
     58 
     59 
     60 static const int KEYTYPE = KEY_TYPE_MD5;
     61 static char      msgbuf[128];
     62 
     63 void
     64 AddTrustedKey(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 
     75 void
     76 AddUntrustedKey(keyid_t keyno)
     77 {
     78 	authtrust(keyno, FALSE);
     79 }
     80 
     81 void test_AddTrustedKeys(void);
     82 void 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 
     94 void test_AddUntrustedKey(void);
     95 void test_AddUntrustedKey(void)
     96 {
     97 	const keyid_t KEYNO = 3;
     98 
     99 	AddUntrustedKey(KEYNO);
    100 
    101 	TEST_ASSERT_FALSE(authistrusted(KEYNO));
    102 }
    103 
    104 void test_HaveKeyCorrect(void);
    105 void 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 
    115 void test_HaveKeyIncorrect(void);
    116 void 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 
    124 void test_AddWithAuthUseKey(void);
    125 void 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 
    133 void test_EmptyKey(void);
    134 void 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 
    144 static u_short
    145 auth_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 
    162 void test_auth_log2(void);
    163 void 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  */
    183 static int/*BOOL*/
    184 getaddr(
    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 
    205 void test_AddrMatch_anull(void);
    206 void 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 
    236 void test_AddrMatch_self4(void);
    237 void 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 
    247 void test_AddrMatch_self6(void);
    248 void 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 
    258 void test_AddrMatch_afmix(void);
    259 void 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 
    270 void test_AddrMatch_ipv4(void);
    271 void 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 
    300 void test_AddrMatch_ipv6(void);
    301 void 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