1 /*
2  **********************************************************************
3  * Copyright (C) Miroslav Lichvar  2020
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  *
18  **********************************************************************
19  */
20 
21 #include <config.h>
22 #include "test.h"
23 
24 #ifdef FEAT_NTS
25 
26 #include <nts_ke_client.c>
27 #include <local.h>
28 
29 static void
prepare_response(NKSN_Instance session,int valid)30 prepare_response(NKSN_Instance session, int valid)
31 {
32   uint16_t data[16];
33   int i, index, length;
34 
35   if (valid)
36     index = -1;
37   else
38     index = random() % 10;
39   DEBUG_LOG("index=%d", index);
40 
41   NKSN_BeginMessage(session);
42 
43   memset(data, 0, sizeof (data));
44   length = 2;
45   assert(sizeof (data[0]) == 2);
46 
47   if (index == 0) {
48     data[0] = htons(random() % 100);
49     TEST_CHECK(NKSN_AddRecord(session, 1, random() % 2 ? NKE_RECORD_ERROR : NKE_RECORD_WARNING,
50                               data, length));
51   } else if (index == 1) {
52     TEST_CHECK(NKSN_AddRecord(session, 1, NKE_RECORD_ERROR + 1000, data, length));
53   }
54 
55   if (index != 2) {
56     if (index == 3)
57       data[0] = htons(NKE_NEXT_PROTOCOL_NTPV4 + random() % 10 + 1);
58     else
59       data[0] = htons(NKE_NEXT_PROTOCOL_NTPV4);
60     if (index == 4)
61       length = 3 + random() % 10;
62     TEST_CHECK(NKSN_AddRecord(session, 1, NKE_RECORD_NEXT_PROTOCOL, data, length));
63   }
64 
65   if (index != 5) {
66     if (index == 6)
67       data[0] = htons(AEAD_AES_SIV_CMAC_256 + random() % 10 + 1);
68     else
69       data[0] = htons(AEAD_AES_SIV_CMAC_256);
70     if (index == 7)
71       length = 3 + random() % 10;
72     TEST_CHECK(NKSN_AddRecord(session, 1, NKE_RECORD_AEAD_ALGORITHM, data, length));
73   }
74 
75   if (random() % 2) {
76     const char server[] = "127.0.0.1";
77     TEST_CHECK(NKSN_AddRecord(session, 1, NKE_RECORD_NTPV4_SERVER_NEGOTIATION,
78                               server, sizeof (server) - 1));
79   }
80 
81   if (random() % 2) {
82     data[0] = htons(123);
83     TEST_CHECK(NKSN_AddRecord(session, 1, NKE_RECORD_NTPV4_PORT_NEGOTIATION, data, length));
84   }
85 
86   if (random() % 2) {
87     length = random() % (sizeof (data) + 1);
88     TEST_CHECK(NKSN_AddRecord(session, 0, 1000 + random() % 1000, data, length));
89   }
90 
91   if (index != 8) {
92     for (i = 0; i < NKE_MAX_COOKIES; i++) {
93       length = (random() % sizeof (data) + 1) / 4 * 4;
94       if (index == 9)
95         length += (length < sizeof (data) ? 1 : -1) * (random() % 3 + 1);
96       TEST_CHECK(NKSN_AddRecord(session, 0, NKE_RECORD_COOKIE, data, length));
97     }
98   }
99 
100   TEST_CHECK(NKSN_EndMessage(session));
101 }
102 
103 void
test_unit(void)104 test_unit(void)
105 {
106   NKC_Instance inst;
107   IPSockAddr addr;
108   int i, r, valid;
109 
110   char conf[][100] = {
111     "nosystemcert",
112   };
113 
114   CNF_Initialise(0, 0);
115   for (i = 0; i < sizeof conf / sizeof conf[0]; i++)
116     CNF_ParseLine(NULL, i + 1, conf[i]);
117 
118   LCL_Initialise();
119 
120   SCK_GetLoopbackIPAddress(AF_INET, &addr.ip_addr);
121   addr.port = 0;
122 
123   inst = NKC_CreateInstance(&addr, "test", 0);
124   TEST_CHECK(inst);
125 
126   for (i = 0; i < 10000; i++) {
127     valid = random() % 2;
128     prepare_response(inst->session, valid);
129     r = process_response(inst);
130     TEST_CHECK(r == valid);
131   }
132 
133   NKC_DestroyInstance(inst);
134 
135   LCL_Finalise();
136   CNF_Finalise();
137 }
138 #else
139 void
test_unit(void)140 test_unit(void)
141 {
142   TEST_REQUIRE(0);
143 }
144 #endif
145