aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/tests
diff options
context:
space:
mode:
authorDavid M. Syzdek <david@syzdek.net>2022-12-31 14:20:40 -0900
committerDavid M. Syzdek <david@syzdek.net>2022-12-31 14:20:40 -0900
commit249186761f117221f96133cd1488ca3ab2542c1c (patch)
treeebeff4af80f99784019d65447585e6644a41de38 /tests
parenta12ecc484992f2a147fa4800ffc81b764641ef42 (diff)
downloadotputils-249186761f117221f96133cd1488ca3ab2542c1c.tar.gz
otputils-249186761f117221f96133cd1488ca3ab2542c1c.tar.bz2
otputils-249186761f117221f96133cd1488ca3ab2542c1c.tar.xz
otputils-249186761f117221f96133cd1488ca3ab2542c1c.zip
test-hotp: adding test
Diffstat (limited to 'tests')
-rw-r--r--tests/test-hotp.c403
1 files changed, 403 insertions, 0 deletions
diff --git a/tests/test-hotp.c b/tests/test-hotp.c
new file mode 100644
index 0000000..b9f9519
--- /dev/null
+++ b/tests/test-hotp.c
@@ -0,0 +1,403 @@
1/*
2 * OTP Utilities
3 * Copyright (C) 2022 David M. Syzdek <david@syzdek.net>.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * * Neither the name of David M. Syzdek nor the
15 * names of its contributors may be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
19 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID M SYZDEK BE LIABLE FOR
22 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30/*
31 * @file tests/test-hotp.c
32 */
33#define _TESTS_TEST_HOTP_C 1
34
35///////////////
36// //
37// Headers //
38// //
39///////////////
40#pragma mark - Headers
41
42#ifdef HAVE_CONFIG_H
43#include <config.h>
44#endif
45
46#include <errno.h>
47#include <assert.h>
48#include <getopt.h>
49#include <stdio.h>
50#include <string.h>
51#include <strings.h>
52#include <inttypes.h>
53
54#include <otputil.h>
55
56
57///////////////////
58// //
59// Definitions //
60// //
61///////////////////
62#pragma mark - Definitions
63
64#ifndef PROGRAM_NAME
65#define PROGRAM_NAME "test-hotp"
66#endif
67#ifndef PACKAGE_BUGREPORT
68#define PACKAGE_BUGREPORT "david@syzdek.net"
69#endif
70#ifndef PACKAGE_COPYRIGHT
71#define PACKAGE_COPYRIGHT ""
72#endif
73#ifndef PACKAGE_NAME
74#define PACKAGE_NAME ""
75#endif
76#ifndef PACKAGE_VERSION
77#define PACKAGE_VERSION ""
78#endif
79
80
81/////////////////
82// //
83// Datatypes //
84// //
85/////////////////
86#pragma mark - Datatypes
87
88typedef struct _test_data testdata_t;
89struct _test_data
90{
91 const char * hotp_kb32;
92 uint64_t hotp_c;
93 int hotp_code;
94 int hotp_digits;
95};
96
97
98/////////////////
99// //
100// Variables //
101// //
102/////////////////
103#pragma mark - Variables
104
105static int verbose = 0;
106static int quiet = 0;
107
108
109static testdata_t test_data[] =
110{
111 // RFC 4226 Appendix D - HOTP Algorithm: Test Values
112 {
113 // count 0 / 6 digits
114 .hotp_kb32 = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ",
115 .hotp_c = 0ULL,
116 .hotp_code = 755224,
117 .hotp_digits = 6,
118 },
119 {
120 // count 1 / 6 digits
121 .hotp_kb32 = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ",
122 .hotp_c = 1ULL,
123 .hotp_code = 287082,
124 .hotp_digits = 6,
125 },
126 {
127 // count 2 / 6 digits
128 .hotp_kb32 = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ",
129 .hotp_c = 2ULL,
130 .hotp_code = 359152,
131 .hotp_digits = 6,
132 },
133 {
134 // count 3 / 6 digits
135 .hotp_kb32 = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ",
136 .hotp_c = 3ULL,
137 .hotp_code = 969429,
138 .hotp_digits = 6,
139 },
140 {
141 // count 4 / 6 digits
142 .hotp_kb32 = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ",
143 .hotp_c = 4ULL,
144 .hotp_code = 338314,
145 .hotp_digits = 6,
146 },
147 {
148 // count 5 / 6 digits
149 .hotp_kb32 = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ",
150 .hotp_c = 5ULL,
151 .hotp_code = 254676,
152 .hotp_digits = 6,
153 },
154 {
155 // count 6 / 6 digits
156 .hotp_kb32 = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ",
157 .hotp_c = 6ULL,
158 .hotp_code = 287922,
159 .hotp_digits = 6,
160 },
161 {
162 // count 7 / 6 digits
163 .hotp_kb32 = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ",
164 .hotp_c = 7ULL,
165 .hotp_code = 162583,
166 .hotp_digits = 6,
167 },
168 {
169 // count 8 / 6 digits
170 .hotp_kb32 = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ",
171 .hotp_c = 8ULL,
172 .hotp_code = 399871,
173 .hotp_digits = 6,
174 },
175 {
176 // count 9 / 6 digits
177 .hotp_kb32 = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ",
178 .hotp_c = 9ULL,
179 .hotp_code = 520489,
180 .hotp_digits = 6,
181 },
182 {
183 // count 0 / 10 digits
184 .hotp_kb32 = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ",
185 .hotp_c = 0ULL,
186 .hotp_code = 1284755224,
187 .hotp_digits = 10,
188 },
189 {
190 // count 0 / 10 digits
191 .hotp_kb32 = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ",
192 .hotp_c = 1ULL,
193 .hotp_code = 1094287082,
194 .hotp_digits = 10,
195 },
196 {
197 // count 2 / 10 digits
198 .hotp_kb32 = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ",
199 .hotp_c = 2ULL,
200 .hotp_code = 137359152,
201 .hotp_digits = 10,
202 },
203 {
204 // count 3 / 10 digits
205 .hotp_kb32 = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ",
206 .hotp_c = 3ULL,
207 .hotp_code = 1726969429,
208 .hotp_digits = 10,
209 },
210 {
211 // count 4 / 10 digits
212 .hotp_kb32 = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ",
213 .hotp_c = 4ULL,
214 .hotp_code = 1640338314,
215 .hotp_digits = 10,
216 },
217 {
218 // count 5 / 10 digits
219 .hotp_kb32 = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ",
220 .hotp_c = 5ULL,
221 .hotp_code = 868254676,
222 .hotp_digits = 10,
223 },
224 {
225 // count 6 / 10 digits
226 .hotp_kb32 = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ",
227 .hotp_c = 6ULL,
228 .hotp_code = 1918287922,
229 .hotp_digits = 10,
230 },
231 {
232 // count 7 / 10 digits
233 .hotp_kb32 = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ",
234 .hotp_c = 7ULL,
235 .hotp_code = 82162583,
236 .hotp_digits = 10,
237 },
238 {
239 // count 8 / 10 digits
240 .hotp_kb32 = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ",
241 .hotp_c = 8ULL,
242 .hotp_code = 673399871,
243 .hotp_digits = 10,
244 },
245 {
246 // count 9 / 10 digits
247 .hotp_kb32 = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ",
248 .hotp_c = 9ULL,
249 .hotp_code = 645520489,
250 .hotp_digits = 10,
251 },
252 {
253 .hotp_kb32 = NULL,
254 .hotp_c = 0,
255 .hotp_code = 0,
256 .hotp_digits = 0,
257 },
258};
259
260
261//////////////////
262// //
263// Prototypes //
264// //
265//////////////////
266#pragma mark - Prototypes
267
268int
269main(
270 int argc,
271 char * argv[] );
272
273
274/////////////////
275// //
276// Functions //
277// //
278/////////////////
279#pragma mark - Functions
280
281int
282main(
283 int argc,
284 char * argv[] )
285{
286 int c;
287 int opt_index;
288 int idx;
289 otputil_bv_t * hotp_k;
290 int64_t hotp_code;
291 testdata_t * p;
292 int len;
293 int k_len;
294 int code_len;
295 char code_str[128];
296
297 // getopt options
298 static const char * short_opt = "hqVv";
299 static struct option long_opt[] =
300 {
301 {"help", no_argument, NULL, 'h' },
302 {"quiet", no_argument, NULL, 'q' },
303 {"silent", no_argument, NULL, 'q' },
304 {"version", no_argument, NULL, 'V' },
305 {"verbose", no_argument, NULL, 'v' },
306 { NULL, 0, NULL, 0 }
307 };
308
309 while((c = getopt_long(argc, argv, short_opt, long_opt, &opt_index)) != -1)
310 {
311 switch(c)
312 {
313 case -1: /* no more arguments */
314 case 0: /* long options toggles */
315 break;
316
317 case 'h':
318 printf("Usage: %s [OPTIONS]\n", PROGRAM_NAME);
319 printf("OPTIONS:\n");
320 printf(" -h, --help print this help and exit\n");
321 printf(" -q, --quiet, --silent do not print messages\n");
322 printf(" -V, --version print version number and exit\n");
323 printf(" -v, --verbose print verbose messages\n");
324 printf("\n");
325 return(0);
326
327 case 'q':
328 quiet++;
329 break;
330
331 case 'V':
332 printf("%s (%s) %s\n", PROGRAM_NAME, PACKAGE_NAME, PACKAGE_VERSION);
333 printf("Written by David M. Syzdek.\n");
334 return(0);
335
336 case 'v':
337 verbose++;
338 break;
339
340 case '?':
341 fprintf(stderr, "Try `%s --help' for more information.\n", PROGRAM_NAME);
342 return(1);
343
344 default:
345 fprintf(stderr, "%s: unrecognized option `--%c'\n", PROGRAM_NAME, c);
346 fprintf(stderr, "Try `%s --help' for more information.\n", PROGRAM_NAME);
347 return(1);
348 };
349 };
350
351 k_len = 0;
352 code_len = 0;
353 if ((verbose))
354 {
355 for(idx = 0; ((test_data[idx].hotp_kb32)); idx++)
356 {
357 if (k_len < (len = (int)strlen(test_data[idx].hotp_kb32)))
358 k_len = len;
359 if (code_len < test_data[idx].hotp_digits)
360 code_len = test_data[idx].hotp_digits;
361 };
362 printf("%-*s : %-2s : digits : %-*s\n", k_len, "key", "c", code_len, "code");
363 };
364
365 for(idx = 0; ((test_data[idx].hotp_kb32)); idx++)
366 {
367 p = &test_data[idx];
368
369 if ((verbose))
370 {
371 snprintf(code_str, sizeof(code_str), "%0*i", p->hotp_digits, p->hotp_code);
372 printf("%*s : %2" PRIu64 " : %6i : %*s\n", k_len, p->hotp_kb32, p->hotp_c, p->hotp_digits, code_len, code_str);
373 };
374
375 otputil_set_param(NULL, OTPUTIL_OPT_HOTP_DIGITS, &p->hotp_digits);
376
377 if ((hotp_k = otputil_base32bv(p->hotp_kb32)) == NULL)
378 {
379 fprintf(stderr, "%s: otputil_base32bv(): internal error\n", PROGRAM_NAME);
380 return(1);
381 };
382
383 if ((hotp_code = otputil_hotp_code(hotp_k, p->hotp_c)) == -1)
384 {
385 fprintf(stderr, "%s: otputil_hotp_code(): internal error\n", PROGRAM_NAME);
386 otputil_bvfree(hotp_k);
387 return(1);
388 };
389
390 otputil_bvfree(hotp_k);
391
392 if (hotp_code != p->hotp_code)
393 {
394 fprintf(stderr, "%s: expected %0*i but generated %0*" PRIi64 "\n", PROGRAM_NAME, p->hotp_digits, p->hotp_code, p->hotp_digits, hotp_code);
395 return(1);
396 };
397 };
398
399 return(0);
400}
401
402
403/* end of source file */