1 /*	$OpenBSD: test-seqnum.c,v 1.1 2024/10/07 12:27:27 tb Exp $ */
2 
3 /*
4  * Copyright (c) 2024 Theo Buehler <tb@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <openssl/asn1.h>
20 #include <openssl/bn.h>
21 
22 #include <err.h>
23 #include <stdio.h>
24 #include <unistd.h>
25 
26 #include "extern.h"
27 
28 #define MAX_DER 25
29 
30 static const struct seqnum {
31 	const char *descr;
32 	const unsigned char der[MAX_DER];
33 	int der_len;
34 	int valid;
35 } seqnum_tests[] = {
36 	{
37 		.descr = "0 - smallest acceptable value:",
38 		.der = {
39 			0x02, 0x01, 0x00,
40 		},
41 		.der_len = 3,
42 		.valid = 1,
43 	},
44 	{
45 		.descr = "1 - acceptable:",
46 		.der = {
47 			0x02, 0x01, 0x01,
48 		},
49 		.der_len = 3,
50 		.valid = 1,
51 	},
52 	{
53 		.descr = "-1 - invalid:",
54 		.der = {
55 			0x02, 0x01, 0xff,
56 		},
57 		.der_len = 3,
58 		.valid = 0,
59 	},
60 	{
61 		.descr = "2^159 - 1 - largest acceptable value:",
62 		.der = {
63 			0x02, 0x14,
64 			0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
65 			0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
66 			0xff, 0xff, 0xff, 0xff,
67 		},
68 		.der_len = 22,
69 		.valid = 1,
70 	},
71 	{
72 		.descr = "-2^159 - invalid, but fits in 20 octets:",
73 		.der = {
74 			0x02, 0x14,
75 			0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
76 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
77 			0x00, 0x00, 0x00, 0x00,
78 		},
79 		.der_len = 22,
80 		.valid = 0,
81 	},
82 	{
83 		.descr = "2^159 - smallest inacceptable positive value:",
84 		.der = {
85 			0x02, 0x15,
86 			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88 			0x00, 0x00, 0x00, 0x00, 0x00,
89 		},
90 		.der_len = 23,
91 		.valid = 0,
92 	},
93 	{
94 		.descr = "2^160 - 1 - largest unsigned 20-bit number:",
95 		.der = {
96 			0x02, 0x15,
97 			0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
98 			0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
99 			0xff, 0xff, 0xff, 0xff, 0xff,
100 		},
101 		.der_len = 23,
102 		.valid = 0,
103 	},
104 	{
105 		.descr = "2^160: too large:",
106 		.der = {
107 			0x02, 0x15,
108 			0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
109 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
110 			0x00, 0x00, 0x00, 0x00, 0x00,
111 		},
112 		.der_len = 23,
113 		.valid = 0,
114 	},
115 };
116 
117 #define N_SEQNUM_TESTS (sizeof(seqnum_tests) / sizeof(seqnum_tests[0]))
118 
119 static int
seqnum_testcase(const struct seqnum * test)120 seqnum_testcase(const struct seqnum *test)
121 {
122 	ASN1_INTEGER *aint = NULL;
123 	const BIGNUM *bn;
124 	const unsigned char *p;
125 	char *s = NULL;
126 	int failed = 1;
127 
128 	p = test->der;
129 	if ((aint = d2i_ASN1_INTEGER(NULL, &p, test->der_len)) == NULL) {
130 		fprintf(stderr, "FAIL: %s d2i_ASN1_INTEGER\n", test->descr);
131 		goto err;
132 	}
133 
134 	s = x509_convert_seqnum(__func__, test->descr, aint);
135 
136 	if (s == NULL && test->valid) {
137 		fprintf(stderr, "FAIL: %s failed to convert seqnum\n",
138 		    test->descr);
139 		goto err;
140 	}
141 	if (s != NULL && !test->valid) {
142 		fprintf(stderr, "FAIL: %s invalid seqnum succeeded\n",
143 		    test->descr);
144 		goto err;
145 	}
146 
147 	failed = 0;
148  err:
149 	ASN1_INTEGER_free(aint);
150 	free(s);
151 
152 	return failed;
153 }
154 
155 static int
seqnum_test(void)156 seqnum_test(void)
157 {
158 	size_t i;
159 	int failed = 0;
160 
161 	for (i = 0; i < N_SEQNUM_TESTS; i++)
162 		failed |= seqnum_testcase(&seqnum_tests[i]);
163 
164 	return failed;
165 }
166 
167 time_t
get_current_time(void)168 get_current_time(void)
169 {
170 	return time(NULL);
171 }
172 
173 int experimental, filemode, outformats, verbose;
174 
175 int
main(void)176 main(void)
177 {
178 	int failed = 0;
179 
180 	failed = seqnum_test();
181 
182 	if (!failed)
183 		printf("OK\n");
184 
185 	return failed;
186 }
187