]>
Commit | Line | Data |
---|---|---|
37332ecc RL |
1 | /* |
2 | * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. | |
3 | * | |
4 | * Licensed under the OpenSSL license (the "License"). You may not use | |
5 | * this file except in compliance with the License. You can obtain a copy | |
6 | * in the file LICENSE in the source distribution or at | |
7 | * https://www.openssl.org/source/license.html | |
8 | */ | |
9 | ||
10 | #include <stdio.h> | |
11 | #include <string.h> | |
12 | ||
64f11ee8 | 13 | #include <openssl/asn1t.h> |
37332ecc RL |
14 | #include "internal/numbers.h" |
15 | #include "test_main.h" | |
16 | #include "testutil.h" | |
17 | ||
18 | #ifdef __GNUC__ | |
19 | # pragma GCC diagnostic ignored "-Wunused-function" | |
20 | # pragma GCC diagnostic ignored "-Wformat" | |
21 | #endif | |
22 | #ifdef __clang__ | |
23 | # pragma clang diagnostic ignored "-Wunused-function" | |
24 | # pragma clang diagnostic ignored "-Wformat" | |
25 | #endif | |
26 | ||
27 | /***** Custom test data ******************************************************/ | |
28 | ||
29 | /* | |
30 | * We conduct tests with these arrays for every type we try out. | |
31 | * You will find the expected results together with the test structures | |
32 | * for each type, further down. | |
33 | */ | |
34 | ||
35 | static unsigned char t_zero[] = { | |
36 | 0x00 | |
37 | }; | |
38 | static unsigned char t_one[] = { | |
39 | 0x01 | |
40 | }; | |
41 | static unsigned char t_longundef[] = { | |
42 | 0x7f, 0xff, 0xff, 0xff | |
43 | }; | |
44 | static unsigned char t_9bytes_1[] = { | |
45 | 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff | |
46 | }; | |
47 | static unsigned char t_8bytes_1[] = { | |
48 | 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
49 | }; | |
50 | static unsigned char t_8bytes_2[] = { | |
51 | 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff | |
52 | }; | |
53 | static unsigned char t_8bytes_3_pad[] = { | |
54 | 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff | |
55 | }; | |
56 | static unsigned char t_8bytes_4_neg[] = { | |
57 | 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
58 | }; | |
59 | static unsigned char t_8bytes_5_negpad[] = { | |
60 | 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
61 | }; | |
62 | ||
63 | /* 32-bit long */ | |
64 | static unsigned char t_5bytes_1[] = { | |
65 | 0x01, 0xff, 0xff, 0xff, 0xff | |
66 | }; | |
67 | static unsigned char t_4bytes_1[] = { | |
68 | 0x00, 0x80, 0x00, 0x00, 0x00 | |
69 | }; | |
70 | /* We make the last byte 0xfe to avoid a clash with ASN1_LONG_UNDEF */ | |
71 | static unsigned char t_4bytes_2[] = { | |
72 | 0x7f, 0xff, 0xff, 0xfe | |
73 | }; | |
74 | static unsigned char t_4bytes_3_pad[] = { | |
75 | 0x00, 0x7f, 0xff, 0xff, 0xfe | |
76 | }; | |
77 | static unsigned char t_4bytes_4_neg[] = { | |
78 | 0x80, 0x00, 0x00, 0x00 | |
79 | }; | |
80 | static unsigned char t_4bytes_5_negpad[] = { | |
81 | 0xff, 0x80, 0x00, 0x00, 0x00 | |
82 | }; | |
83 | ||
84 | typedef struct { | |
85 | unsigned char *bytes1; | |
86 | size_t nbytes1; | |
87 | unsigned char *bytes2; | |
88 | size_t nbytes2; | |
89 | } TEST_CUSTOM_DATA; | |
90 | #define CUSTOM_DATA(v) \ | |
91 | { v, sizeof(v), t_one, sizeof(t_one) }, \ | |
92 | { t_one, sizeof(t_one), v, sizeof(v) } | |
93 | ||
94 | static TEST_CUSTOM_DATA test_custom_data[] = { | |
95 | CUSTOM_DATA(t_zero), | |
96 | CUSTOM_DATA(t_longundef), | |
97 | CUSTOM_DATA(t_one), | |
98 | CUSTOM_DATA(t_9bytes_1), | |
99 | CUSTOM_DATA(t_8bytes_1), | |
100 | CUSTOM_DATA(t_8bytes_2), | |
101 | CUSTOM_DATA(t_8bytes_3_pad), | |
102 | CUSTOM_DATA(t_8bytes_4_neg), | |
103 | CUSTOM_DATA(t_8bytes_5_negpad), | |
104 | CUSTOM_DATA(t_5bytes_1), | |
105 | CUSTOM_DATA(t_4bytes_1), | |
106 | CUSTOM_DATA(t_4bytes_2), | |
107 | CUSTOM_DATA(t_4bytes_3_pad), | |
108 | CUSTOM_DATA(t_4bytes_4_neg), | |
109 | CUSTOM_DATA(t_4bytes_5_negpad), | |
110 | }; | |
111 | ||
112 | ||
113 | /***** Type specific test data ***********************************************/ | |
114 | ||
115 | /* | |
116 | * First, a few utility things that all type specific data can use, or in some | |
117 | * cases, MUST use. | |
118 | */ | |
119 | ||
120 | /* | |
121 | * For easy creation of arrays of expected data. These macros correspond to | |
122 | * the uses of CUSTOM_DATA above. | |
123 | */ | |
124 | #define CUSTOM_EXPECTED_SUCCESS(num, znum) \ | |
125 | { 0xff, num, 1 }, \ | |
126 | { 0xff, 1, znum } | |
127 | #define CUSTOM_EXPECTED_FAILURE \ | |
128 | { 0, 0, 0 }, \ | |
129 | { 0, 0, 0 } | |
130 | ||
131 | /* | |
132 | * A structure to collect all test information in. There MUST be one instance | |
133 | * of this for each test | |
134 | */ | |
135 | typedef int i2d_fn(void **a, unsigned char **pp); | |
136 | typedef void *d2i_fn(void **a, unsigned char **pp, long length); | |
137 | typedef void ifree_fn(void *a); | |
138 | typedef struct { | |
139 | char *name; | |
140 | int skip; /* 1 if this package should be skipped */ | |
141 | ||
142 | /* An array of structures to compare decoded custom data with */ | |
143 | void *encode_expectations; | |
144 | size_t encode_expectations_size; | |
145 | size_t encode_expectations_elem_size; | |
146 | ||
147 | /* | |
148 | * An array of structures that are encoded into a DER blob, which is | |
149 | * then decoded, and result gets compared with the original. | |
150 | */ | |
151 | void *encdec_data; | |
152 | size_t encdec_data_size; | |
153 | size_t encdec_data_elem_size; | |
154 | ||
155 | /* The i2d function to use with this type */ | |
156 | i2d_fn *i2d; | |
157 | /* The d2i function to use with this type */ | |
158 | d2i_fn *d2i; | |
159 | /* Function to free a decoded structure */ | |
160 | ifree_fn *ifree; | |
161 | } TEST_PACKAGE; | |
162 | ||
163 | /* To facilitate the creation of an encdec_data array */ | |
164 | #define ENCDEC_DATA(num, znum) \ | |
165 | { 0xff, num, 1 }, { 0xff, 1, znum } | |
166 | #define ENCDEC_ARRAY(max, zmax, min, zmin) \ | |
167 | ENCDEC_DATA(max,zmax), \ | |
168 | ENCDEC_DATA(min,zmin), \ | |
169 | ENCDEC_DATA(1, 1), \ | |
170 | ENCDEC_DATA(-1, -1), \ | |
171 | ENCDEC_DATA(0, ASN1_LONG_UNDEF) | |
172 | ||
31ae5161 | 173 | #if OPENSSL_API_COMPAT < 0x10200000L |
37332ecc RL |
174 | /***** LONG ******************************************************************/ |
175 | ||
176 | typedef struct { | |
177 | /* If decoding is expected to succeed, set this to 1, otherwise 0 */ | |
178 | ASN1_BOOLEAN success; | |
179 | long test_long; | |
180 | long test_zlong; | |
181 | } ASN1_LONG_DATA; | |
182 | ||
183 | ASN1_SEQUENCE(ASN1_LONG_DATA) = { | |
184 | ASN1_SIMPLE(ASN1_LONG_DATA, success, ASN1_FBOOLEAN), | |
185 | ASN1_SIMPLE(ASN1_LONG_DATA, test_long, LONG), | |
186 | ASN1_EXP_OPT(ASN1_LONG_DATA, test_zlong, ZLONG, 0) | |
187 | } static_ASN1_SEQUENCE_END(ASN1_LONG_DATA) | |
188 | ||
189 | IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_LONG_DATA) | |
190 | IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_LONG_DATA) | |
191 | ||
192 | static ASN1_LONG_DATA long_expected_32bit[] = { | |
193 | /* The following should fail on the second because it's the default */ | |
194 | { 0xff, 0, 1 }, { 0, 0, 0 }, /* t_zero */ | |
195 | { 0, 0, 0 }, { 0xff, 1, 0x7fffffff }, /* t_longundef */ | |
196 | CUSTOM_EXPECTED_SUCCESS(1, 1), /* t_one */ | |
197 | CUSTOM_EXPECTED_FAILURE, /* t_9bytes_1 */ | |
198 | CUSTOM_EXPECTED_FAILURE, /* t_8bytes_1 */ | |
199 | CUSTOM_EXPECTED_FAILURE, /* t_8bytes_2 */ | |
200 | CUSTOM_EXPECTED_FAILURE, /* t_8bytes_3_pad */ | |
201 | CUSTOM_EXPECTED_FAILURE, /* t_8bytes_4_neg */ | |
202 | CUSTOM_EXPECTED_FAILURE, /* t_8bytes_5_negpad */ | |
203 | CUSTOM_EXPECTED_FAILURE, /* t_5bytes_1 */ | |
204 | CUSTOM_EXPECTED_FAILURE, /* t_4bytes_1 (too large positive) */ | |
205 | CUSTOM_EXPECTED_SUCCESS(INT32_MAX - 1, INT32_MAX -1), /* t_4bytes_2 */ | |
206 | CUSTOM_EXPECTED_FAILURE, /* t_4bytes_3_pad (illegal padding) */ | |
207 | CUSTOM_EXPECTED_SUCCESS(INT32_MIN, INT32_MIN), /* t_4bytes_4_neg */ | |
208 | CUSTOM_EXPECTED_FAILURE, /* t_4bytes_5_negpad (illegal padding) */ | |
209 | }; | |
210 | static ASN1_LONG_DATA long_encdec_data_32bit[] = { | |
211 | ENCDEC_ARRAY(LONG_MAX - 1, LONG_MAX, LONG_MIN, LONG_MIN), | |
212 | /* Check that default numbers fail */ | |
213 | { 0, ASN1_LONG_UNDEF, 1 }, { 0, 1, 0 } | |
214 | }; | |
215 | ||
216 | static TEST_PACKAGE long_test_package_32bit = { | |
217 | "LONG", sizeof(long) != 4, | |
218 | long_expected_32bit, | |
219 | sizeof(long_expected_32bit), sizeof(long_expected_32bit[0]), | |
220 | long_encdec_data_32bit, | |
221 | sizeof(long_encdec_data_32bit), sizeof(long_encdec_data_32bit[0]), | |
222 | (i2d_fn *)i2d_ASN1_LONG_DATA, (d2i_fn *)d2i_ASN1_LONG_DATA, | |
223 | (ifree_fn *)ASN1_LONG_DATA_free | |
224 | }; | |
225 | ||
226 | static ASN1_LONG_DATA long_expected_64bit[] = { | |
227 | /* The following should fail on the second because it's the default */ | |
228 | { 0xff, 0, 1 }, { 0, 0, 0 }, /* t_zero */ | |
229 | { 0, 0, 0 }, { 0xff, 1, 0x7fffffff }, /* t_longundef */ | |
230 | CUSTOM_EXPECTED_SUCCESS(1, 1), /* t_one */ | |
231 | CUSTOM_EXPECTED_FAILURE, /* t_9bytes_1 */ | |
232 | CUSTOM_EXPECTED_FAILURE, /* t_8bytes_1 */ | |
233 | CUSTOM_EXPECTED_SUCCESS(LONG_MAX, LONG_MAX), /* t_8bytes_2 */ | |
234 | CUSTOM_EXPECTED_FAILURE, /* t_8bytes_3_pad (illegal padding) */ | |
235 | CUSTOM_EXPECTED_SUCCESS(LONG_MIN, LONG_MIN), /* t_8bytes_4_neg */ | |
236 | CUSTOM_EXPECTED_FAILURE, /* t_8bytes_5_negpad (illegal padding) */ | |
237 | CUSTOM_EXPECTED_SUCCESS((long)0x1ffffffff, (long)0x1ffffffff), /* t_5bytes_1 */ | |
238 | CUSTOM_EXPECTED_SUCCESS((long)0x80000000, (long)0x80000000), /* t_4bytes_1 */ | |
239 | CUSTOM_EXPECTED_SUCCESS(INT32_MAX - 1, INT32_MAX -1), /* t_4bytes_2 */ | |
240 | CUSTOM_EXPECTED_FAILURE, /* t_4bytes_3_pad (illegal padding) */ | |
241 | CUSTOM_EXPECTED_SUCCESS(INT32_MIN, INT32_MIN), /* t_4bytes_4_neg */ | |
242 | CUSTOM_EXPECTED_FAILURE, /* t_4bytes_5_negpad (illegal padding) */ | |
243 | }; | |
244 | static ASN1_LONG_DATA long_encdec_data_64bit[] = { | |
245 | ENCDEC_ARRAY(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN), | |
246 | /* Check that default numbers fail */ | |
247 | { 0, ASN1_LONG_UNDEF, 1 }, { 0, 1, 0 } | |
248 | }; | |
249 | ||
250 | static TEST_PACKAGE long_test_package_64bit = { | |
251 | "LONG", sizeof(long) != 8, | |
252 | long_expected_64bit, | |
253 | sizeof(long_expected_64bit), sizeof(long_expected_64bit[0]), | |
254 | long_encdec_data_64bit, | |
255 | sizeof(long_encdec_data_64bit), sizeof(long_encdec_data_64bit[0]), | |
256 | (i2d_fn *)i2d_ASN1_LONG_DATA, (d2i_fn *)d2i_ASN1_LONG_DATA, | |
257 | (ifree_fn *)ASN1_LONG_DATA_free | |
258 | }; | |
31ae5161 | 259 | #endif |
37332ecc RL |
260 | |
261 | /***** INT32 *****************************************************************/ | |
262 | ||
263 | typedef struct { | |
264 | ASN1_BOOLEAN success; | |
265 | int32_t test_int32; | |
266 | int32_t test_zint32; | |
267 | } ASN1_INT32_DATA; | |
268 | ||
269 | ASN1_SEQUENCE(ASN1_INT32_DATA) = { | |
5748e4dc | 270 | ASN1_SIMPLE(ASN1_INT32_DATA, success, ASN1_FBOOLEAN), |
37332ecc RL |
271 | ASN1_SIMPLE(ASN1_INT32_DATA, test_int32, INT32), |
272 | ASN1_EXP_OPT(ASN1_INT32_DATA, test_zint32, ZINT32, 0) | |
273 | } static_ASN1_SEQUENCE_END(ASN1_INT32_DATA) | |
274 | ||
275 | IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_INT32_DATA) | |
276 | IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_INT32_DATA) | |
277 | ||
278 | static ASN1_INT32_DATA int32_expected[] = { | |
279 | CUSTOM_EXPECTED_SUCCESS(0, 0), /* t_zero */ | |
280 | CUSTOM_EXPECTED_SUCCESS(ASN1_LONG_UNDEF, ASN1_LONG_UNDEF), /* t_zero */ | |
281 | CUSTOM_EXPECTED_SUCCESS(1, 1), /* t_one */ | |
282 | CUSTOM_EXPECTED_FAILURE, /* t_9bytes_1 */ | |
283 | CUSTOM_EXPECTED_FAILURE, /* t_8bytes_1 */ | |
284 | CUSTOM_EXPECTED_FAILURE, /* t_8bytes_2 */ | |
285 | CUSTOM_EXPECTED_FAILURE, /* t_8bytes_3_pad */ | |
286 | CUSTOM_EXPECTED_FAILURE, /* t_8bytes_4_neg */ | |
287 | CUSTOM_EXPECTED_FAILURE, /* t_8bytes_5_negpad */ | |
288 | CUSTOM_EXPECTED_FAILURE, /* t_5bytes_1 */ | |
289 | CUSTOM_EXPECTED_FAILURE, /* t_4bytes_1 (too large positive) */ | |
290 | CUSTOM_EXPECTED_SUCCESS(INT32_MAX - 1, INT32_MAX -1), /* t_4bytes_2 */ | |
291 | CUSTOM_EXPECTED_FAILURE, /* t_4bytes_3_pad (illegal padding) */ | |
292 | CUSTOM_EXPECTED_SUCCESS(INT32_MIN, INT32_MIN), /* t_4bytes_4_neg */ | |
293 | CUSTOM_EXPECTED_FAILURE, /* t_4bytes_5_negpad (illegal padding) */ | |
294 | }; | |
295 | static ASN1_INT32_DATA int32_encdec_data[] = { | |
296 | ENCDEC_ARRAY(INT32_MAX, INT32_MAX, INT32_MIN, INT32_MIN), | |
297 | }; | |
298 | ||
299 | static TEST_PACKAGE int32_test_package = { | |
300 | "INT32", 0, | |
301 | int32_expected, sizeof(int32_expected), sizeof(int32_expected[0]), | |
302 | int32_encdec_data, sizeof(int32_encdec_data), sizeof(int32_encdec_data[0]), | |
303 | (i2d_fn *)i2d_ASN1_INT32_DATA, (d2i_fn *)d2i_ASN1_INT32_DATA, | |
304 | (ifree_fn *)ASN1_INT32_DATA_free | |
305 | }; | |
306 | ||
307 | /***** UINT32 ****************************************************************/ | |
308 | ||
309 | typedef struct { | |
310 | ASN1_BOOLEAN success; | |
311 | uint32_t test_uint32; | |
312 | uint32_t test_zuint32; | |
313 | } ASN1_UINT32_DATA; | |
314 | ||
315 | ASN1_SEQUENCE(ASN1_UINT32_DATA) = { | |
5748e4dc | 316 | ASN1_SIMPLE(ASN1_UINT32_DATA, success, ASN1_FBOOLEAN), |
37332ecc RL |
317 | ASN1_SIMPLE(ASN1_UINT32_DATA, test_uint32, UINT32), |
318 | ASN1_EXP_OPT(ASN1_UINT32_DATA, test_zuint32, ZUINT32, 0) | |
319 | } static_ASN1_SEQUENCE_END(ASN1_UINT32_DATA) | |
320 | ||
321 | IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_UINT32_DATA) | |
322 | IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_UINT32_DATA) | |
323 | ||
324 | static ASN1_UINT32_DATA uint32_expected[] = { | |
325 | CUSTOM_EXPECTED_SUCCESS(0, 0), /* t_zero */ | |
326 | CUSTOM_EXPECTED_SUCCESS(ASN1_LONG_UNDEF, ASN1_LONG_UNDEF), /* t_zero */ | |
327 | CUSTOM_EXPECTED_SUCCESS(1, 1), /* t_one */ | |
328 | CUSTOM_EXPECTED_FAILURE, /* t_9bytes_1 */ | |
329 | CUSTOM_EXPECTED_FAILURE, /* t_8bytes_1 */ | |
330 | CUSTOM_EXPECTED_FAILURE, /* t_8bytes_2 */ | |
331 | CUSTOM_EXPECTED_FAILURE, /* t_8bytes_3_pad */ | |
332 | CUSTOM_EXPECTED_FAILURE, /* t_8bytes_4_neg */ | |
333 | CUSTOM_EXPECTED_FAILURE, /* t_8bytes_5_negpad */ | |
334 | CUSTOM_EXPECTED_FAILURE, /* t_5bytes_1 */ | |
335 | CUSTOM_EXPECTED_SUCCESS(0x80000000, 0x80000000), /* t_4bytes_1 */ | |
336 | CUSTOM_EXPECTED_SUCCESS(INT32_MAX - 1, INT32_MAX -1), /* t_4bytes_2 */ | |
337 | CUSTOM_EXPECTED_FAILURE, /* t_4bytes_3_pad (illegal padding) */ | |
338 | CUSTOM_EXPECTED_FAILURE, /* t_4bytes_4_neg (illegal negative value) */ | |
339 | CUSTOM_EXPECTED_FAILURE, /* t_4bytes_5_negpad (illegal padding) */ | |
340 | }; | |
341 | static ASN1_UINT32_DATA uint32_encdec_data[] = { | |
342 | ENCDEC_ARRAY(UINT32_MAX, UINT32_MAX, 0, 0), | |
343 | }; | |
344 | ||
345 | static TEST_PACKAGE uint32_test_package = { | |
346 | "UINT32", 0, | |
347 | uint32_expected, sizeof(uint32_expected), sizeof(uint32_expected[0]), | |
348 | uint32_encdec_data, sizeof(uint32_encdec_data), sizeof(uint32_encdec_data[0]), | |
349 | (i2d_fn *)i2d_ASN1_UINT32_DATA, (d2i_fn *)d2i_ASN1_UINT32_DATA, | |
350 | (ifree_fn *)ASN1_UINT32_DATA_free | |
351 | }; | |
352 | ||
353 | /***** INT64 *****************************************************************/ | |
354 | ||
355 | typedef struct { | |
356 | ASN1_BOOLEAN success; | |
357 | int64_t test_int64; | |
358 | int64_t test_zint64; | |
359 | } ASN1_INT64_DATA; | |
360 | ||
361 | ASN1_SEQUENCE(ASN1_INT64_DATA) = { | |
5748e4dc | 362 | ASN1_SIMPLE(ASN1_INT64_DATA, success, ASN1_FBOOLEAN), |
37332ecc RL |
363 | ASN1_SIMPLE(ASN1_INT64_DATA, test_int64, INT64), |
364 | ASN1_EXP_OPT(ASN1_INT64_DATA, test_zint64, ZINT64, 0) | |
365 | } static_ASN1_SEQUENCE_END(ASN1_INT64_DATA) | |
366 | ||
367 | IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_INT64_DATA) | |
368 | IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_INT64_DATA) | |
369 | ||
370 | static ASN1_INT64_DATA int64_expected[] = { | |
371 | CUSTOM_EXPECTED_SUCCESS(0, 0), /* t_zero */ | |
372 | CUSTOM_EXPECTED_SUCCESS(ASN1_LONG_UNDEF, ASN1_LONG_UNDEF), /* t_zero */ | |
373 | CUSTOM_EXPECTED_SUCCESS(1, 1), /* t_one */ | |
374 | CUSTOM_EXPECTED_FAILURE, /* t_9bytes_1 */ | |
375 | CUSTOM_EXPECTED_SUCCESS(INT64_MIN, INT64_MIN), /* t_8bytes_1 */ | |
376 | CUSTOM_EXPECTED_SUCCESS(INT64_MAX, INT64_MAX), /* t_8bytes_2 */ | |
377 | CUSTOM_EXPECTED_FAILURE, /* t_8bytes_3_pad (illegal padding) */ | |
378 | CUSTOM_EXPECTED_SUCCESS(INT64_MIN, INT64_MIN), /* t_8bytes_4_neg */ | |
379 | CUSTOM_EXPECTED_FAILURE, /* t_8bytes_5_negpad (illegal padding) */ | |
380 | CUSTOM_EXPECTED_SUCCESS(0x1ffffffff, 0x1ffffffff), /* t_5bytes_1 */ | |
381 | CUSTOM_EXPECTED_SUCCESS(0x80000000, 0x80000000), /* t_4bytes_1 */ | |
382 | CUSTOM_EXPECTED_SUCCESS(INT32_MAX - 1, INT32_MAX -1), /* t_4bytes_2 */ | |
383 | CUSTOM_EXPECTED_FAILURE, /* t_4bytes_3_pad (illegal padding) */ | |
384 | CUSTOM_EXPECTED_SUCCESS(0x80000000, 0x80000000), /* t_4bytes_4_neg */ | |
385 | CUSTOM_EXPECTED_FAILURE, /* t_4bytes_5_negpad (illegal padding) */ | |
386 | }; | |
387 | static ASN1_INT64_DATA int64_encdec_data[] = { | |
388 | ENCDEC_ARRAY(INT64_MAX, INT64_MAX, INT64_MIN, INT64_MIN), | |
389 | ENCDEC_ARRAY(INT32_MAX, INT32_MAX, INT32_MIN, INT32_MIN), | |
390 | }; | |
391 | ||
392 | static TEST_PACKAGE int64_test_package = { | |
393 | "INT64", 0, | |
394 | int64_expected, sizeof(int64_expected), sizeof(int64_expected[0]), | |
395 | int64_encdec_data, sizeof(int64_encdec_data), sizeof(int64_encdec_data[0]), | |
396 | (i2d_fn *)i2d_ASN1_INT64_DATA, (d2i_fn *)d2i_ASN1_INT64_DATA, | |
397 | (ifree_fn *)ASN1_INT64_DATA_free | |
398 | }; | |
399 | ||
400 | /***** UINT64 ****************************************************************/ | |
401 | ||
402 | typedef struct { | |
403 | ASN1_BOOLEAN success; | |
404 | uint64_t test_uint64; | |
405 | uint64_t test_zuint64; | |
406 | } ASN1_UINT64_DATA; | |
407 | ||
408 | ASN1_SEQUENCE(ASN1_UINT64_DATA) = { | |
5748e4dc | 409 | ASN1_SIMPLE(ASN1_UINT64_DATA, success, ASN1_FBOOLEAN), |
37332ecc RL |
410 | ASN1_SIMPLE(ASN1_UINT64_DATA, test_uint64, UINT64), |
411 | ASN1_EXP_OPT(ASN1_UINT64_DATA, test_zuint64, ZUINT64, 0) | |
412 | } static_ASN1_SEQUENCE_END(ASN1_UINT64_DATA) | |
413 | ||
414 | IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_UINT64_DATA) | |
415 | IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_UINT64_DATA) | |
416 | ||
417 | static ASN1_UINT64_DATA uint64_expected[] = { | |
418 | CUSTOM_EXPECTED_SUCCESS(0, 0), /* t_zero */ | |
419 | CUSTOM_EXPECTED_SUCCESS(ASN1_LONG_UNDEF, ASN1_LONG_UNDEF), /* t_zero */ | |
420 | CUSTOM_EXPECTED_SUCCESS(1, 1), /* t_one */ | |
421 | CUSTOM_EXPECTED_FAILURE, /* t_9bytes_1 */ | |
422 | CUSTOM_EXPECTED_SUCCESS(INT64_MIN, INT64_MIN), /* t_8bytes_1 */ | |
423 | CUSTOM_EXPECTED_SUCCESS(INT64_MAX, INT64_MAX), /* t_8bytes_2 */ | |
424 | CUSTOM_EXPECTED_FAILURE, /* t_8bytes_3_pad */ | |
425 | CUSTOM_EXPECTED_FAILURE, /* t_8bytes_4_neg */ | |
426 | CUSTOM_EXPECTED_FAILURE, /* t_8bytes_5_negpad */ | |
427 | CUSTOM_EXPECTED_SUCCESS(0x1ffffffff, 0x1ffffffff), /* t_5bytes_1 */ | |
428 | CUSTOM_EXPECTED_SUCCESS(0x80000000, 0x80000000), /* t_4bytes_1 */ | |
429 | CUSTOM_EXPECTED_SUCCESS(INT32_MAX - 1, INT32_MAX -1), /* t_4bytes_2 */ | |
430 | CUSTOM_EXPECTED_FAILURE, /* t_4bytes_3_pad (illegal padding) */ | |
431 | CUSTOM_EXPECTED_FAILURE, /* t_4bytes_4_neg (illegal negative value) */ | |
432 | CUSTOM_EXPECTED_FAILURE, /* t_4bytes_5_negpad (illegal padding) */ | |
433 | }; | |
434 | static ASN1_UINT64_DATA uint64_encdec_data[] = { | |
435 | ENCDEC_ARRAY(UINT64_MAX, UINT64_MAX, 0, 0), | |
436 | }; | |
437 | ||
438 | static TEST_PACKAGE uint64_test_package = { | |
439 | "UINT64", 0, | |
440 | uint64_expected, sizeof(uint64_expected), sizeof(uint64_expected[0]), | |
441 | uint64_encdec_data, sizeof(uint64_encdec_data), sizeof(uint64_encdec_data[0]), | |
442 | (i2d_fn *)i2d_ASN1_UINT64_DATA, (d2i_fn *)d2i_ASN1_UINT64_DATA, | |
443 | (ifree_fn *)ASN1_UINT64_DATA_free | |
444 | }; | |
445 | ||
446 | /***** General testing functions *********************************************/ | |
447 | ||
448 | ||
449 | /* Template structure to map onto any test data structure */ | |
450 | typedef struct { | |
451 | ASN1_BOOLEAN success; | |
452 | unsigned char bytes[1]; /* In reality, there's more */ | |
453 | } EXPECTED; | |
454 | ||
455 | /* | |
456 | * do_decode returns a tristate: | |
457 | * | |
458 | * -1 Couldn't decode | |
459 | * 0 decoded structure wasn't what was expected (failure) | |
460 | * 1 decoded structure was what was expected (success) | |
461 | */ | |
462 | static int do_decode(unsigned char *bytes, long nbytes, | |
463 | const EXPECTED *expected, size_t expected_size, | |
464 | const TEST_PACKAGE *package) | |
465 | { | |
466 | EXPECTED *enctst = NULL; | |
467 | const unsigned char *start; | |
468 | int ret = 0; | |
469 | ||
470 | start = bytes; | |
471 | enctst = package->d2i(NULL, &bytes, nbytes); | |
472 | if (enctst == NULL) { | |
473 | if (expected->success == 0) { | |
474 | ret = 1; | |
475 | ERR_clear_error(); | |
476 | } else { | |
477 | ret = -1; | |
478 | } | |
479 | } else { | |
480 | if (start + nbytes == bytes | |
481 | && memcmp(enctst, expected, expected_size) == 0) | |
482 | ret = 1; | |
483 | else | |
484 | ret = 0; | |
485 | } | |
486 | ||
487 | package->ifree(enctst); | |
488 | return ret; | |
489 | } | |
490 | ||
491 | /* Do an encode/decode round trip */ | |
492 | static int do_enc_dec(EXPECTED *bytes, long nbytes, | |
493 | const TEST_PACKAGE *package) | |
494 | { | |
495 | unsigned char *data = NULL; | |
496 | int len; | |
497 | int ret = 0; | |
498 | void *p = bytes; | |
499 | ||
500 | len = package->i2d(p, &data); | |
501 | if (len < 0) | |
502 | return -1; | |
503 | ||
504 | ret = do_decode(data, len, bytes, nbytes, package); | |
505 | OPENSSL_free(data); | |
506 | return ret; | |
507 | } | |
508 | ||
509 | static size_t der_encode_length(size_t len, unsigned char **pp) | |
510 | { | |
511 | size_t lenbytes; | |
512 | ||
513 | OPENSSL_assert(len < 0x8000); | |
514 | if (len > 255) | |
515 | lenbytes = 3; | |
516 | else if (len > 127) | |
517 | lenbytes = 2; | |
518 | else | |
519 | lenbytes = 1; | |
520 | ||
521 | if (pp != NULL) { | |
522 | if (lenbytes == 1) { | |
523 | *(*pp)++ = len; | |
524 | } else { | |
525 | *(*pp)++ = lenbytes - 1; | |
526 | if (lenbytes == 2) { | |
527 | *(*pp)++ = 0x80 | len; | |
528 | } else { | |
529 | *(*pp)++ = 0x80 | (len >> 8); | |
530 | *(*pp)++ = len & 0xff; | |
531 | } | |
532 | } | |
533 | } | |
534 | return lenbytes; | |
535 | } | |
536 | ||
537 | /* Attempt to decode a custom encoding of the test structure */ | |
538 | static int do_decode_custom(const TEST_CUSTOM_DATA *custom_data, | |
539 | const EXPECTED *expected, size_t expected_size, | |
540 | const TEST_PACKAGE *package) | |
541 | { | |
542 | size_t firstbytes, secondbytes, secondbytesinner, seqbytes; | |
543 | const unsigned char t_true[] = { V_ASN1_BOOLEAN, 0x01, 0xff }; | |
544 | unsigned char *encoding, *p = NULL; | |
545 | int ret; | |
546 | ||
547 | /* | |
548 | * The first item is just an INTEGER tag, INTEGER length and INTEGER content | |
549 | */ | |
550 | firstbytes = | |
551 | 1 + der_encode_length(custom_data->nbytes1, NULL) | |
552 | + custom_data->nbytes1; | |
553 | ||
554 | /* | |
555 | * The second item is an explicit tag, content length, INTEGER tag, | |
556 | * INTEGER length, INTEGER bytes | |
557 | */ | |
558 | secondbytesinner = | |
559 | 1 + der_encode_length(custom_data->nbytes2, NULL) | |
560 | + custom_data->nbytes2; | |
561 | secondbytes = | |
562 | 1 + der_encode_length(secondbytesinner, NULL) + secondbytesinner; | |
563 | ||
564 | /* | |
565 | * The whole sequence is the sequence tag, content length, BOOLEAN true | |
566 | * (copied from t_true), the first (firstbytes) and second (secondbytes) | |
567 | * items | |
568 | */ | |
569 | seqbytes = | |
570 | 1 + der_encode_length(sizeof(t_true) + firstbytes + secondbytes, NULL) | |
571 | + sizeof(t_true) + firstbytes + secondbytes; | |
572 | ||
573 | encoding = p = OPENSSL_malloc(seqbytes); | |
574 | if (encoding == NULL) | |
575 | return -1; | |
576 | ||
577 | /* Sequence tag */ | |
578 | *p++ = 0x30; | |
579 | der_encode_length(sizeof(t_true) + firstbytes + secondbytes, &p); | |
580 | ||
581 | /* ASN1_BOOLEAN TRUE */ | |
582 | memcpy(p, t_true, sizeof(t_true)); /* Marks decoding success */ | |
583 | p += sizeof(t_true); | |
584 | ||
585 | /* First INTEGER item (non-optional) */ | |
586 | *p++ = V_ASN1_INTEGER; | |
587 | der_encode_length(custom_data->nbytes1, &p); | |
588 | memcpy(p, custom_data->bytes1, custom_data->nbytes1); | |
589 | p += custom_data->nbytes1; | |
590 | ||
591 | /* Second INTEGER item (optional) */ | |
592 | /* Start with the explicit optional tag */ | |
593 | *p++ = 0xa0; | |
594 | der_encode_length(secondbytesinner, &p); | |
595 | *p++ = V_ASN1_INTEGER; | |
596 | der_encode_length(custom_data->nbytes2, &p); | |
597 | memcpy(p, custom_data->bytes2, custom_data->nbytes2); | |
598 | p += custom_data->nbytes2; | |
599 | ||
600 | OPENSSL_assert(seqbytes == (size_t)(p - encoding)); | |
601 | ||
602 | ret = do_decode(encoding, seqbytes, expected, expected_size, package); | |
603 | OPENSSL_free(encoding); | |
604 | ||
605 | return ret; | |
606 | } | |
607 | ||
608 | ||
609 | static int test_intern(const TEST_PACKAGE *package) | |
610 | { | |
611 | unsigned int i; | |
612 | size_t nelems; | |
613 | int fail = 0; | |
614 | ||
615 | if (package->skip) | |
616 | return 1; | |
617 | ||
618 | /* Do decode_custom checks */ | |
619 | nelems = package->encode_expectations_size | |
620 | / package->encode_expectations_elem_size; | |
621 | OPENSSL_assert(nelems == | |
622 | sizeof(test_custom_data) / sizeof(test_custom_data[0])); | |
623 | for (i = 0; i < nelems; i++) { | |
624 | size_t pos = i * package->encode_expectations_elem_size; | |
625 | switch (do_decode_custom(&test_custom_data[i], | |
626 | (EXPECTED *)&((unsigned char *)package | |
627 | ->encode_expectations)[pos], | |
628 | package->encode_expectations_elem_size, | |
629 | package)) { | |
630 | case -1: | |
631 | fprintf(stderr, "Failed custom decode round trip %u of %s\n", | |
632 | i, package->name); | |
633 | ERR_print_errors_fp(stderr); | |
634 | fail++; | |
635 | ERR_clear_error(); | |
636 | break; | |
637 | case 0: | |
638 | fprintf(stderr, "Custom decode round trip %u of %s mismatch\n", | |
639 | i, package->name); | |
640 | fail++; | |
641 | break; | |
642 | case 1: | |
643 | break; | |
644 | default: | |
645 | OPENSSL_die("do_enc_dec() return unknown value", | |
646 | __FILE__, __LINE__); | |
647 | } | |
648 | } | |
649 | ||
650 | /* Do enc_dec checks */ | |
651 | nelems = package->encdec_data_size / package->encdec_data_elem_size; | |
652 | for (i = 0; i < nelems; i++) { | |
653 | size_t pos = i * package->encdec_data_elem_size; | |
654 | switch (do_enc_dec((EXPECTED *)&((unsigned char *)package | |
655 | ->encdec_data)[pos], | |
656 | package->encdec_data_elem_size, | |
657 | package)) { | |
658 | case -1: | |
659 | fprintf(stderr, "Failed encode/decode round trip %u of %s\n", | |
660 | i, package->name); | |
661 | ERR_print_errors_fp(stderr); | |
662 | ERR_clear_error(); | |
663 | fail++; | |
664 | break; | |
665 | case 0: | |
666 | fprintf(stderr, "Encode/decode round trip %u of %s mismatch\n", | |
667 | i, package->name); | |
668 | fail++; | |
669 | break; | |
670 | case 1: | |
671 | break; | |
672 | default: | |
673 | OPENSSL_die("do_enc_dec() return unknown value", | |
674 | __FILE__, __LINE__); | |
675 | } | |
676 | } | |
677 | ||
678 | return fail == 0; | |
679 | } | |
680 | ||
31ae5161 | 681 | #if OPENSSL_API_COMPAT < 0x10200000L |
37332ecc RL |
682 | static int test_long_32bit(void) |
683 | { | |
684 | return test_intern(&long_test_package_32bit); | |
685 | } | |
686 | ||
687 | static int test_long_64bit(void) | |
688 | { | |
689 | return test_intern(&long_test_package_64bit); | |
690 | } | |
31ae5161 | 691 | #endif |
37332ecc RL |
692 | |
693 | static int test_int32(void) | |
694 | { | |
695 | return test_intern(&int32_test_package); | |
696 | } | |
697 | ||
698 | static int test_uint32(void) | |
699 | { | |
700 | return test_intern(&uint32_test_package); | |
701 | } | |
702 | ||
703 | static int test_int64(void) | |
704 | { | |
705 | return test_intern(&int64_test_package); | |
706 | } | |
707 | ||
708 | static int test_uint64(void) | |
709 | { | |
710 | return test_intern(&uint64_test_package); | |
711 | } | |
712 | ||
713 | void register_tests(void) | |
714 | { | |
31ae5161 | 715 | #if OPENSSL_API_COMPAT < 0x10200000L |
37332ecc RL |
716 | ADD_TEST(test_long_32bit); |
717 | ADD_TEST(test_long_64bit); | |
31ae5161 | 718 | #endif |
37332ecc RL |
719 | ADD_TEST(test_int32); |
720 | ADD_TEST(test_uint32); | |
721 | ADD_TEST(test_int64); | |
722 | ADD_TEST(test_uint64); | |
723 | } |