1/*
2 * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (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
13#include <openssl/rand.h>
14#include <openssl/asn1t.h>
15#include "internal/numbers.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
35static unsigned char t_zero[] = {
36    0x00
37};
38static unsigned char t_one[] = {
39    0x01
40};
41static unsigned char t_one_neg[] = {
42    0xff
43};
44static unsigned char t_minus_256[] = {
45    0xff, 0x00
46};
47static unsigned char t_longundef[] = {
48    0x7f, 0xff, 0xff, 0xff
49};
50static unsigned char t_9bytes_1[] = {
51    0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
52};
53static unsigned char t_8bytes_1[] = {
54    0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
55};
56static unsigned char t_8bytes_2[] = {
57    0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
58};
59static unsigned char t_8bytes_3_pad[] = {
60    0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
61};
62static unsigned char t_8bytes_4_neg[] = {
63    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
64};
65static unsigned char t_8bytes_5_negpad[] = {
66    0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
67};
68
69/* 32-bit long */
70static unsigned char t_5bytes_1[] = {
71    0x01, 0xff, 0xff, 0xff, 0xff
72};
73static unsigned char t_4bytes_1[] = {
74    0x00, 0x80, 0x00, 0x00, 0x00
75};
76/* We make the last byte 0xfe to avoid a clash with ASN1_LONG_UNDEF */
77static unsigned char t_4bytes_2[] = {
78    0x7f, 0xff, 0xff, 0xfe
79};
80static unsigned char t_4bytes_3_pad[] = {
81    0x00, 0x7f, 0xff, 0xff, 0xfe
82};
83static unsigned char t_4bytes_4_neg[] = {
84    0x80, 0x00, 0x00, 0x00
85};
86static unsigned char t_4bytes_5_negpad[] = {
87    0xff, 0x80, 0x00, 0x00, 0x00
88};
89
90typedef struct {
91    unsigned char *bytes1;
92    size_t nbytes1;
93    unsigned char *bytes2;
94    size_t nbytes2;
95} TEST_CUSTOM_DATA;
96#define CUSTOM_DATA(v)                          \
97    { v, sizeof(v), t_one, sizeof(t_one) },     \
98    { t_one, sizeof(t_one), v, sizeof(v) }
99
100static TEST_CUSTOM_DATA test_custom_data[] = {
101    CUSTOM_DATA(t_zero),
102    CUSTOM_DATA(t_longundef),
103    CUSTOM_DATA(t_one),
104    CUSTOM_DATA(t_one_neg),
105    CUSTOM_DATA(t_minus_256),
106    CUSTOM_DATA(t_9bytes_1),
107    CUSTOM_DATA(t_8bytes_1),
108    CUSTOM_DATA(t_8bytes_2),
109    CUSTOM_DATA(t_8bytes_3_pad),
110    CUSTOM_DATA(t_8bytes_4_neg),
111    CUSTOM_DATA(t_8bytes_5_negpad),
112    CUSTOM_DATA(t_5bytes_1),
113    CUSTOM_DATA(t_4bytes_1),
114    CUSTOM_DATA(t_4bytes_2),
115    CUSTOM_DATA(t_4bytes_3_pad),
116    CUSTOM_DATA(t_4bytes_4_neg),
117    CUSTOM_DATA(t_4bytes_5_negpad),
118};
119
120
121/***** Type specific test data ***********************************************/
122
123/*
124 * First, a few utility things that all type specific data can use, or in some
125 * cases, MUST use.
126 */
127
128/*
129 * For easy creation of arrays of expected data.  These macros correspond to
130 * the uses of CUSTOM_DATA above.
131 */
132#define CUSTOM_EXPECTED_SUCCESS(num, znum)      \
133    { 0xff, num, 1 },                           \
134    { 0xff, 1, znum }
135#define CUSTOM_EXPECTED_FAILURE                 \
136    { 0, 0, 0 },                                \
137    { 0, 0, 0 }
138
139/*
140 * A structure to collect all test information in.  There MUST be one instance
141 * of this for each test
142 */
143typedef int i2d_fn(void *a, unsigned char **pp);
144typedef void *d2i_fn(void **a, unsigned char **pp, long length);
145typedef void ifree_fn(void *a);
146typedef struct {
147    ASN1_ITEM_EXP *asn1_type;
148    const char *name;
149    int skip;                    /* 1 if this package should be skipped */
150
151    /* An array of structures to compare decoded custom data with */
152    void *encode_expectations;
153    size_t encode_expectations_size;
154    size_t encode_expectations_elem_size;
155
156    /*
157     * An array of structures that are encoded into a DER blob, which is
158     * then decoded, and result gets compared with the original.
159     */
160    void *encdec_data;
161    size_t encdec_data_size;
162    size_t encdec_data_elem_size;
163
164    /* The i2d function to use with this type */
165    i2d_fn *i2d;
166    /* The d2i function to use with this type */
167    d2i_fn *d2i;
168    /* Function to free a decoded structure */
169    ifree_fn *ifree;
170} TEST_PACKAGE;
171
172/* To facilitate the creation of an encdec_data array */
173#define ENCDEC_DATA(num, znum)                  \
174    { 0xff, num, 1 }, { 0xff, 1, znum }
175#define ENCDEC_ARRAY(max, zmax, min, zmin)      \
176    ENCDEC_DATA(max,zmax),                      \
177    ENCDEC_DATA(min,zmin),                      \
178    ENCDEC_DATA(1, 1),                          \
179    ENCDEC_DATA(-1, -1),                        \
180    ENCDEC_DATA(0, ASN1_LONG_UNDEF)
181
182#ifndef OPENSSL_NO_DEPRECATED_3_0
183/***** LONG ******************************************************************/
184
185typedef struct {
186    /* If decoding is expected to succeed, set this to 1, otherwise 0 */
187    ASN1_BOOLEAN success;
188    long test_long;
189    long test_zlong;
190} ASN1_LONG_DATA;
191
192ASN1_SEQUENCE(ASN1_LONG_DATA) = {
193    ASN1_SIMPLE(ASN1_LONG_DATA, success, ASN1_BOOLEAN),
194    ASN1_SIMPLE(ASN1_LONG_DATA, test_long, LONG),
195    ASN1_EXP_OPT(ASN1_LONG_DATA, test_zlong, ZLONG, 0)
196} static_ASN1_SEQUENCE_END(ASN1_LONG_DATA)
197
198IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_LONG_DATA)
199IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_LONG_DATA)
200
201static ASN1_LONG_DATA long_expected_32bit[] = {
202    /* The following should fail on the second because it's the default */
203    { 0xff, 0, 1 }, { 0, 0, 0 }, /* t_zero */
204    { 0, 0, 0 }, { 0xff, 1, 0x7fffffff }, /* t_longundef */
205    CUSTOM_EXPECTED_SUCCESS(1, 1), /* t_one */
206    CUSTOM_EXPECTED_SUCCESS(-1, -1), /* t_one_neg */
207    CUSTOM_EXPECTED_SUCCESS(-256, -256), /* t_minus_256 */
208    CUSTOM_EXPECTED_FAILURE,     /* t_9bytes_1 */
209    CUSTOM_EXPECTED_FAILURE,     /* t_8bytes_1 */
210    CUSTOM_EXPECTED_FAILURE,     /* t_8bytes_2 */
211    CUSTOM_EXPECTED_FAILURE,     /* t_8bytes_3_pad */
212    CUSTOM_EXPECTED_FAILURE,     /* t_8bytes_4_neg */
213    CUSTOM_EXPECTED_FAILURE,     /* t_8bytes_5_negpad */
214    CUSTOM_EXPECTED_FAILURE,     /* t_5bytes_1 */
215    CUSTOM_EXPECTED_FAILURE,     /* t_4bytes_1 (too large positive) */
216    CUSTOM_EXPECTED_SUCCESS(INT32_MAX - 1, INT32_MAX -1), /* t_4bytes_2 */
217    CUSTOM_EXPECTED_FAILURE,     /* t_4bytes_3_pad (illegal padding) */
218    CUSTOM_EXPECTED_SUCCESS(INT32_MIN, INT32_MIN), /* t_4bytes_4_neg */
219    CUSTOM_EXPECTED_FAILURE,     /* t_4bytes_5_negpad (illegal padding) */
220};
221static ASN1_LONG_DATA long_encdec_data_32bit[] = {
222    ENCDEC_ARRAY(LONG_MAX - 1, LONG_MAX, LONG_MIN, LONG_MIN),
223    /* Check that default numbers fail */
224    { 0, ASN1_LONG_UNDEF, 1 }, { 0, 1, 0 }
225};
226
227static TEST_PACKAGE long_test_package_32bit = {
228    ASN1_ITEM_ref(ASN1_LONG_DATA), "LONG", sizeof(long) != 4,
229    long_expected_32bit,
230    sizeof(long_expected_32bit), sizeof(long_expected_32bit[0]),
231    long_encdec_data_32bit,
232    sizeof(long_encdec_data_32bit), sizeof(long_encdec_data_32bit[0]),
233    (i2d_fn *)i2d_ASN1_LONG_DATA, (d2i_fn *)d2i_ASN1_LONG_DATA,
234    (ifree_fn *)ASN1_LONG_DATA_free
235};
236
237static ASN1_LONG_DATA long_expected_64bit[] = {
238    /* The following should fail on the second because it's the default */
239    { 0xff, 0, 1 }, { 0, 0, 0 }, /* t_zero */
240    { 0, 0, 0 }, { 0xff, 1, 0x7fffffff }, /* t_longundef */
241    CUSTOM_EXPECTED_SUCCESS(1, 1), /* t_one */
242    CUSTOM_EXPECTED_SUCCESS(-1, -1), /* t_one_neg */
243    CUSTOM_EXPECTED_SUCCESS(-256, -256), /* t_minus_256 */
244    CUSTOM_EXPECTED_FAILURE,     /* t_9bytes_1 */
245    CUSTOM_EXPECTED_FAILURE,     /* t_8bytes_1 */
246    CUSTOM_EXPECTED_SUCCESS(LONG_MAX, LONG_MAX), /* t_8bytes_2 */
247    CUSTOM_EXPECTED_FAILURE,     /* t_8bytes_3_pad (illegal padding) */
248    CUSTOM_EXPECTED_SUCCESS(LONG_MIN, LONG_MIN), /* t_8bytes_4_neg */
249    CUSTOM_EXPECTED_FAILURE,     /* t_8bytes_5_negpad (illegal padding) */
250    CUSTOM_EXPECTED_SUCCESS((long)0x1ffffffff, (long)0x1ffffffff), /* t_5bytes_1 */
251    CUSTOM_EXPECTED_SUCCESS((long)0x80000000, (long)0x80000000), /* t_4bytes_1 */
252    CUSTOM_EXPECTED_SUCCESS(INT32_MAX - 1, INT32_MAX -1), /* t_4bytes_2 */
253    CUSTOM_EXPECTED_FAILURE,     /* t_4bytes_3_pad (illegal padding) */
254    CUSTOM_EXPECTED_SUCCESS(INT32_MIN, INT32_MIN), /* t_4bytes_4_neg */
255    CUSTOM_EXPECTED_FAILURE,     /* t_4bytes_5_negpad (illegal padding) */
256};
257static ASN1_LONG_DATA long_encdec_data_64bit[] = {
258    ENCDEC_ARRAY(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN),
259    /* Check that default numbers fail */
260    { 0, ASN1_LONG_UNDEF, 1 }, { 0, 1, 0 }
261};
262
263static TEST_PACKAGE long_test_package_64bit = {
264    ASN1_ITEM_ref(ASN1_LONG_DATA), "LONG", sizeof(long) != 8,
265    long_expected_64bit,
266    sizeof(long_expected_64bit), sizeof(long_expected_64bit[0]),
267    long_encdec_data_64bit,
268    sizeof(long_encdec_data_64bit), sizeof(long_encdec_data_64bit[0]),
269    (i2d_fn *)i2d_ASN1_LONG_DATA, (d2i_fn *)d2i_ASN1_LONG_DATA,
270    (ifree_fn *)ASN1_LONG_DATA_free
271};
272#endif
273
274/***** INT32 *****************************************************************/
275
276typedef struct {
277    ASN1_BOOLEAN success;
278    int32_t test_int32;
279    int32_t test_zint32;
280} ASN1_INT32_DATA;
281
282ASN1_SEQUENCE(ASN1_INT32_DATA) = {
283    ASN1_SIMPLE(ASN1_INT32_DATA, success, ASN1_BOOLEAN),
284    ASN1_EMBED(ASN1_INT32_DATA, test_int32, INT32),
285    ASN1_EXP_OPT_EMBED(ASN1_INT32_DATA, test_zint32, ZINT32, 0)
286} static_ASN1_SEQUENCE_END(ASN1_INT32_DATA)
287
288IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_INT32_DATA)
289IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_INT32_DATA)
290
291static ASN1_INT32_DATA int32_expected[] = {
292    CUSTOM_EXPECTED_SUCCESS(0, 0), /* t_zero */
293    CUSTOM_EXPECTED_SUCCESS(ASN1_LONG_UNDEF, ASN1_LONG_UNDEF), /* t_zero */
294    CUSTOM_EXPECTED_SUCCESS(1, 1), /* t_one */
295    CUSTOM_EXPECTED_SUCCESS(-1, -1), /* t_one_neg */
296    CUSTOM_EXPECTED_SUCCESS(-256, -256), /* t_minus_256 */
297    CUSTOM_EXPECTED_FAILURE,     /* t_9bytes_1 */
298    CUSTOM_EXPECTED_FAILURE,     /* t_8bytes_1 */
299    CUSTOM_EXPECTED_FAILURE,     /* t_8bytes_2 */
300    CUSTOM_EXPECTED_FAILURE,     /* t_8bytes_3_pad */
301    CUSTOM_EXPECTED_FAILURE,     /* t_8bytes_4_neg */
302    CUSTOM_EXPECTED_FAILURE,     /* t_8bytes_5_negpad */
303    CUSTOM_EXPECTED_FAILURE,     /* t_5bytes_1 */
304    CUSTOM_EXPECTED_FAILURE,     /* t_4bytes_1 (too large positive) */
305    CUSTOM_EXPECTED_SUCCESS(INT32_MAX - 1, INT32_MAX -1), /* t_4bytes_2 */
306    CUSTOM_EXPECTED_FAILURE,     /* t_4bytes_3_pad (illegal padding) */
307    CUSTOM_EXPECTED_SUCCESS(INT32_MIN, INT32_MIN), /* t_4bytes_4_neg */
308    CUSTOM_EXPECTED_FAILURE,     /* t_4bytes_5_negpad (illegal padding) */
309};
310static ASN1_INT32_DATA int32_encdec_data[] = {
311    ENCDEC_ARRAY(INT32_MAX, INT32_MAX, INT32_MIN, INT32_MIN),
312};
313
314static TEST_PACKAGE int32_test_package = {
315    ASN1_ITEM_ref(ASN1_INT32_DATA), "INT32", 0,
316    int32_expected, sizeof(int32_expected), sizeof(int32_expected[0]),
317    int32_encdec_data, sizeof(int32_encdec_data), sizeof(int32_encdec_data[0]),
318    (i2d_fn *)i2d_ASN1_INT32_DATA, (d2i_fn *)d2i_ASN1_INT32_DATA,
319    (ifree_fn *)ASN1_INT32_DATA_free
320};
321
322/***** UINT32 ****************************************************************/
323
324typedef struct {
325    ASN1_BOOLEAN success;
326    uint32_t test_uint32;
327    uint32_t test_zuint32;
328} ASN1_UINT32_DATA;
329
330ASN1_SEQUENCE(ASN1_UINT32_DATA) = {
331    ASN1_SIMPLE(ASN1_UINT32_DATA, success, ASN1_BOOLEAN),
332    ASN1_EMBED(ASN1_UINT32_DATA, test_uint32, UINT32),
333    ASN1_EXP_OPT_EMBED(ASN1_UINT32_DATA, test_zuint32, ZUINT32, 0)
334} static_ASN1_SEQUENCE_END(ASN1_UINT32_DATA)
335
336IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_UINT32_DATA)
337IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_UINT32_DATA)
338
339static ASN1_UINT32_DATA uint32_expected[] = {
340    CUSTOM_EXPECTED_SUCCESS(0, 0), /* t_zero */
341    CUSTOM_EXPECTED_SUCCESS(ASN1_LONG_UNDEF, ASN1_LONG_UNDEF), /* t_zero */
342    CUSTOM_EXPECTED_SUCCESS(1, 1), /* t_one */
343    CUSTOM_EXPECTED_FAILURE,     /* t_one_neg (illegal negative value) */
344    CUSTOM_EXPECTED_FAILURE,     /* t_minus_256 (illegal negative value) */
345    CUSTOM_EXPECTED_FAILURE,     /* t_9bytes_1 */
346    CUSTOM_EXPECTED_FAILURE,     /* t_8bytes_1 */
347    CUSTOM_EXPECTED_FAILURE,     /* t_8bytes_2 */
348    CUSTOM_EXPECTED_FAILURE,     /* t_8bytes_3_pad */
349    CUSTOM_EXPECTED_FAILURE,     /* t_8bytes_4_neg */
350    CUSTOM_EXPECTED_FAILURE,     /* t_8bytes_5_negpad */
351    CUSTOM_EXPECTED_FAILURE,     /* t_5bytes_1 */
352    CUSTOM_EXPECTED_SUCCESS(0x80000000, 0x80000000), /* t_4bytes_1 */
353    CUSTOM_EXPECTED_SUCCESS(INT32_MAX - 1, INT32_MAX -1), /* t_4bytes_2 */
354    CUSTOM_EXPECTED_FAILURE,     /* t_4bytes_3_pad (illegal padding) */
355    CUSTOM_EXPECTED_FAILURE,     /* t_4bytes_4_neg (illegal negative value) */
356    CUSTOM_EXPECTED_FAILURE,     /* t_4bytes_5_negpad (illegal padding) */
357};
358static ASN1_UINT32_DATA uint32_encdec_data[] = {
359    ENCDEC_ARRAY(UINT32_MAX, UINT32_MAX, 0, 0),
360};
361
362static TEST_PACKAGE uint32_test_package = {
363    ASN1_ITEM_ref(ASN1_UINT32_DATA), "UINT32", 0,
364    uint32_expected, sizeof(uint32_expected), sizeof(uint32_expected[0]),
365    uint32_encdec_data, sizeof(uint32_encdec_data), sizeof(uint32_encdec_data[0]),
366    (i2d_fn *)i2d_ASN1_UINT32_DATA, (d2i_fn *)d2i_ASN1_UINT32_DATA,
367    (ifree_fn *)ASN1_UINT32_DATA_free
368};
369
370/***** INT64 *****************************************************************/
371
372typedef struct {
373    ASN1_BOOLEAN success;
374    int64_t test_int64;
375    int64_t test_zint64;
376} ASN1_INT64_DATA;
377
378ASN1_SEQUENCE(ASN1_INT64_DATA) = {
379    ASN1_SIMPLE(ASN1_INT64_DATA, success, ASN1_BOOLEAN),
380    ASN1_EMBED(ASN1_INT64_DATA, test_int64, INT64),
381    ASN1_EXP_OPT_EMBED(ASN1_INT64_DATA, test_zint64, ZINT64, 0)
382} static_ASN1_SEQUENCE_END(ASN1_INT64_DATA)
383
384IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_INT64_DATA)
385IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_INT64_DATA)
386
387static ASN1_INT64_DATA int64_expected[] = {
388    CUSTOM_EXPECTED_SUCCESS(0, 0), /* t_zero */
389    CUSTOM_EXPECTED_SUCCESS(ASN1_LONG_UNDEF, ASN1_LONG_UNDEF), /* t_zero */
390    CUSTOM_EXPECTED_SUCCESS(1, 1), /* t_one */
391    CUSTOM_EXPECTED_SUCCESS(-1, -1), /* t_one_neg */
392    CUSTOM_EXPECTED_SUCCESS(-256, -256), /* t_minus_256 */
393    CUSTOM_EXPECTED_FAILURE,     /* t_9bytes_1 */
394    CUSTOM_EXPECTED_FAILURE,     /* t_8bytes_1 (too large positive) */
395    CUSTOM_EXPECTED_SUCCESS(INT64_MAX, INT64_MAX), /* t_8bytes_2 */
396    CUSTOM_EXPECTED_FAILURE,     /* t_8bytes_3_pad (illegal padding) */
397    CUSTOM_EXPECTED_SUCCESS(INT64_MIN, INT64_MIN), /* t_8bytes_4_neg */
398    CUSTOM_EXPECTED_FAILURE,     /* t_8bytes_5_negpad (illegal padding) */
399    CUSTOM_EXPECTED_SUCCESS(0x1ffffffffULL, 0x1ffffffffULL), /* t_5bytes_1 */
400    CUSTOM_EXPECTED_SUCCESS(0x80000000, 0x80000000), /* t_4bytes_1 */
401    CUSTOM_EXPECTED_SUCCESS(INT32_MAX - 1, INT32_MAX -1), /* t_4bytes_2 */
402    CUSTOM_EXPECTED_FAILURE,     /* t_4bytes_3_pad (illegal padding) */
403    CUSTOM_EXPECTED_SUCCESS(INT32_MIN, INT32_MIN), /* t_4bytes_4_neg */
404    CUSTOM_EXPECTED_FAILURE,     /* t_4bytes_5_negpad (illegal padding) */
405};
406static ASN1_INT64_DATA int64_encdec_data[] = {
407    ENCDEC_ARRAY(INT64_MAX, INT64_MAX, INT64_MIN, INT64_MIN),
408    ENCDEC_ARRAY(INT32_MAX, INT32_MAX, INT32_MIN, INT32_MIN),
409};
410
411static TEST_PACKAGE int64_test_package = {
412    ASN1_ITEM_ref(ASN1_INT64_DATA), "INT64", 0,
413    int64_expected, sizeof(int64_expected), sizeof(int64_expected[0]),
414    int64_encdec_data, sizeof(int64_encdec_data), sizeof(int64_encdec_data[0]),
415    (i2d_fn *)i2d_ASN1_INT64_DATA, (d2i_fn *)d2i_ASN1_INT64_DATA,
416    (ifree_fn *)ASN1_INT64_DATA_free
417};
418
419/***** UINT64 ****************************************************************/
420
421typedef struct {
422    ASN1_BOOLEAN success;
423    uint64_t test_uint64;
424    uint64_t test_zuint64;
425} ASN1_UINT64_DATA;
426
427ASN1_SEQUENCE(ASN1_UINT64_DATA) = {
428    ASN1_SIMPLE(ASN1_UINT64_DATA, success, ASN1_BOOLEAN),
429    ASN1_EMBED(ASN1_UINT64_DATA, test_uint64, UINT64),
430    ASN1_EXP_OPT_EMBED(ASN1_UINT64_DATA, test_zuint64, ZUINT64, 0)
431} static_ASN1_SEQUENCE_END(ASN1_UINT64_DATA)
432
433IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_UINT64_DATA)
434IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_UINT64_DATA)
435
436static ASN1_UINT64_DATA uint64_expected[] = {
437    CUSTOM_EXPECTED_SUCCESS(0, 0), /* t_zero */
438    CUSTOM_EXPECTED_SUCCESS(ASN1_LONG_UNDEF, ASN1_LONG_UNDEF), /* t_zero */
439    CUSTOM_EXPECTED_SUCCESS(1, 1), /* t_one */
440    CUSTOM_EXPECTED_FAILURE,     /* t_one_neg (illegal negative value) */
441    CUSTOM_EXPECTED_FAILURE,     /* t_minus_256 (illegal negative value) */
442    CUSTOM_EXPECTED_FAILURE,     /* t_9bytes_1 */
443    CUSTOM_EXPECTED_SUCCESS((uint64_t)INT64_MAX+1, (uint64_t)INT64_MAX+1),
444                                 /* t_8bytes_1 */
445    CUSTOM_EXPECTED_SUCCESS(INT64_MAX, INT64_MAX), /* t_8bytes_2 */
446    CUSTOM_EXPECTED_FAILURE,     /* t_8bytes_3_pad */
447    CUSTOM_EXPECTED_FAILURE,     /* t_8bytes_4_neg */
448    CUSTOM_EXPECTED_FAILURE,     /* t_8bytes_5_negpad */
449    CUSTOM_EXPECTED_SUCCESS(0x1ffffffffULL, 0x1ffffffffULL), /* t_5bytes_1 */
450    CUSTOM_EXPECTED_SUCCESS(0x80000000, 0x80000000), /* t_4bytes_1 */
451    CUSTOM_EXPECTED_SUCCESS(INT32_MAX - 1, INT32_MAX -1), /* t_4bytes_2 */
452    CUSTOM_EXPECTED_FAILURE,     /* t_4bytes_3_pad (illegal padding) */
453    CUSTOM_EXPECTED_FAILURE,     /* t_4bytes_4_neg (illegal negative value) */
454    CUSTOM_EXPECTED_FAILURE,     /* t_4bytes_5_negpad (illegal padding) */
455};
456static ASN1_UINT64_DATA uint64_encdec_data[] = {
457    ENCDEC_ARRAY(UINT64_MAX, UINT64_MAX, 0, 0),
458};
459
460static TEST_PACKAGE uint64_test_package = {
461    ASN1_ITEM_ref(ASN1_UINT64_DATA), "UINT64", 0,
462    uint64_expected, sizeof(uint64_expected), sizeof(uint64_expected[0]),
463    uint64_encdec_data, sizeof(uint64_encdec_data), sizeof(uint64_encdec_data[0]),
464    (i2d_fn *)i2d_ASN1_UINT64_DATA, (d2i_fn *)d2i_ASN1_UINT64_DATA,
465    (ifree_fn *)ASN1_UINT64_DATA_free
466};
467
468/***** General testing functions *********************************************/
469
470
471/* Template structure to map onto any test data structure */
472typedef struct {
473    ASN1_BOOLEAN success;
474    unsigned char bytes[1];       /* In reality, there's more */
475} EXPECTED;
476
477/*
478 * do_decode returns a tristate:
479 *
480 *      -1      Couldn't decode
481 *      0       decoded structure wasn't what was expected (failure)
482 *      1       decoded structure was what was expected (success)
483 */
484static int do_decode(unsigned char *bytes, long nbytes,
485                     const EXPECTED *expected, size_t expected_size,
486                     const TEST_PACKAGE *package)
487{
488    EXPECTED *enctst = NULL;
489    const unsigned char *start;
490    int ret = 0;
491
492    start = bytes;
493    enctst = package->d2i(NULL, &bytes, nbytes);
494    if (enctst == NULL) {
495        if (expected->success == 0) {
496            ret = 1;
497            ERR_clear_error();
498        } else {
499            ret = -1;
500        }
501    } else {
502        if (start + nbytes == bytes
503            && memcmp(enctst, expected, expected_size) == 0)
504            ret = 1;
505        else
506            ret = 0;
507    }
508
509    package->ifree(enctst);
510    return ret;
511}
512
513/*
514 * do_encode returns a tristate:
515 *
516 *      -1      Couldn't encode
517 *      0       encoded DER wasn't what was expected (failure)
518 *      1       encoded DER was what was expected (success)
519 */
520static int do_encode(EXPECTED *input,
521                     const unsigned char *expected, size_t expected_len,
522                     const TEST_PACKAGE *package)
523{
524    unsigned char *data = NULL;
525    int len;
526    int ret = 0;
527
528    len = package->i2d(input, &data);
529    if (len < 0)
530        return -1;
531
532    if ((size_t)len != expected_len
533        || memcmp(data, expected, expected_len) != 0) {
534        if (input->success == 0) {
535            ret = 1;
536            ERR_clear_error();
537        } else {
538            ret = 0;
539        }
540    } else {
541        ret = 1;
542    }
543
544    OPENSSL_free(data);
545    return ret;
546}
547
548/* Do an encode/decode round trip */
549static int do_enc_dec(EXPECTED *bytes, long nbytes,
550                      const TEST_PACKAGE *package)
551{
552    unsigned char *data = NULL;
553    int len;
554    int ret = 0;
555    void *p = bytes;
556
557    len = package->i2d(p, &data);
558    if (len < 0)
559        return -1;
560
561    ret = do_decode(data, len, bytes, nbytes, package);
562    OPENSSL_free(data);
563    return ret;
564}
565
566static size_t der_encode_length(size_t len, unsigned char **pp)
567{
568    size_t lenbytes;
569
570    OPENSSL_assert(len < 0x8000);
571    if (len > 255)
572        lenbytes = 3;
573    else if (len > 127)
574        lenbytes = 2;
575    else
576        lenbytes = 1;
577
578    if (pp != NULL) {
579        if (lenbytes == 1) {
580            *(*pp)++ = (unsigned char)len;
581        } else {
582            *(*pp)++ = (unsigned char)(lenbytes - 1);
583            if (lenbytes == 2) {
584                *(*pp)++ = (unsigned char)(0x80 | len);
585            } else {
586                *(*pp)++ = (unsigned char)(0x80 | (len >> 8));
587                *(*pp)++ = (unsigned char)(len);
588            }
589        }
590    }
591    return lenbytes;
592}
593
594static size_t make_custom_der(const TEST_CUSTOM_DATA *custom_data,
595                              unsigned char **encoding, int explicit_default)
596{
597    size_t firstbytes, secondbytes = 0, secondbytesinner = 0, seqbytes;
598    const unsigned char t_true[] = { V_ASN1_BOOLEAN, 0x01, 0xff };
599    unsigned char *p = NULL;
600    size_t i;
601
602    /*
603     * The first item is just an INTEGER tag, INTEGER length and INTEGER content
604     */
605    firstbytes =
606        1 + der_encode_length(custom_data->nbytes1, NULL)
607        + custom_data->nbytes1;
608
609    for (i = custom_data->nbytes2; i > 0; i--) {
610        if (custom_data->bytes2[i - 1] != '\0')
611            break;
612    }
613    if (explicit_default || i > 0) {
614        /*
615         * The second item is an explicit tag, content length, INTEGER tag,
616         * INTEGER length, INTEGER bytes
617         */
618        secondbytesinner =
619            1 + der_encode_length(custom_data->nbytes2, NULL)
620            + custom_data->nbytes2;
621        secondbytes =
622            1 + der_encode_length(secondbytesinner, NULL) + secondbytesinner;
623    }
624
625    /*
626     * The whole sequence is the sequence tag, content length, BOOLEAN true
627     * (copied from t_true), the first (firstbytes) and second (secondbytes)
628     * items
629     */
630    seqbytes =
631        1 + der_encode_length(sizeof(t_true) + firstbytes + secondbytes, NULL)
632        + sizeof(t_true) + firstbytes + secondbytes;
633
634    *encoding = p = OPENSSL_malloc(seqbytes);
635    if (*encoding == NULL)
636        return 0;
637
638    /* Sequence tag */
639    *p++ = 0x30;
640    der_encode_length(sizeof(t_true) + firstbytes + secondbytes, &p);
641
642    /* ASN1_BOOLEAN TRUE */
643    memcpy(p, t_true, sizeof(t_true)); /* Marks decoding success */
644    p += sizeof(t_true);
645
646    /* First INTEGER item (non-optional) */
647    *p++ = V_ASN1_INTEGER;
648    der_encode_length(custom_data->nbytes1, &p);
649    memcpy(p, custom_data->bytes1, custom_data->nbytes1);
650    p += custom_data->nbytes1;
651
652    if (secondbytes > 0) {
653        /* Second INTEGER item (optional) */
654        /* Start with the explicit optional tag */
655        *p++ = 0xa0;
656        der_encode_length(secondbytesinner, &p);
657        *p++ = V_ASN1_INTEGER;
658        der_encode_length(custom_data->nbytes2, &p);
659        memcpy(p, custom_data->bytes2, custom_data->nbytes2);
660        p += custom_data->nbytes2;
661    }
662
663    OPENSSL_assert(seqbytes == (size_t)(p - *encoding));
664
665    return seqbytes;
666}
667
668/* Attempt to decode a custom encoding of the test structure */
669static int do_decode_custom(const TEST_CUSTOM_DATA *custom_data,
670                            const EXPECTED *expected, size_t expected_size,
671                            const TEST_PACKAGE *package)
672{
673    unsigned char *encoding = NULL;
674    /*
675     * We force the defaults to be explicitly encoded to make sure we test
676     * for defaults that shouldn't be present (i.e. we check for failure)
677     */
678    size_t encoding_length = make_custom_der(custom_data, &encoding, 1);
679    int ret;
680
681    if (encoding_length == 0)
682        return -1;
683
684    ret = do_decode(encoding, encoding_length, expected, expected_size,
685                    package);
686    OPENSSL_free(encoding);
687
688    return ret;
689}
690
691/* Attempt to encode the test structure and compare it to custom DER */
692static int do_encode_custom(EXPECTED *input,
693                            const TEST_CUSTOM_DATA *custom_data,
694                            const TEST_PACKAGE *package)
695{
696    unsigned char *expected = NULL;
697    size_t expected_length = make_custom_der(custom_data, &expected, 0);
698    int ret;
699
700    if (expected_length == 0)
701        return -1;
702
703    ret = do_encode(input, expected, expected_length, package);
704    OPENSSL_free(expected);
705
706    return ret;
707}
708
709static int do_print_item(const TEST_PACKAGE *package)
710{
711#define DATA_BUF_SIZE 256
712    const ASN1_ITEM *i = ASN1_ITEM_ptr(package->asn1_type);
713    ASN1_VALUE *o;
714    int ret;
715
716    OPENSSL_assert(package->encode_expectations_elem_size <= DATA_BUF_SIZE);
717    if ((o = OPENSSL_malloc(DATA_BUF_SIZE)) == NULL)
718        return 0;
719
720    (void)RAND_bytes((unsigned char*)o,
721                     (int)package->encode_expectations_elem_size);
722    ret = ASN1_item_print(bio_err, o, 0, i, NULL);
723    OPENSSL_free(o);
724
725    return ret;
726}
727
728
729static int test_intern(const TEST_PACKAGE *package)
730{
731    unsigned int i;
732    size_t nelems;
733    int fail = 0;
734
735    if (package->skip)
736        return 1;
737
738    /* Do decode_custom checks */
739    nelems = package->encode_expectations_size
740        / package->encode_expectations_elem_size;
741    OPENSSL_assert(nelems ==
742                   sizeof(test_custom_data) / sizeof(test_custom_data[0]));
743    for (i = 0; i < nelems; i++) {
744        size_t pos = i * package->encode_expectations_elem_size;
745        EXPECTED *expected
746            = (EXPECTED *)&((unsigned char *)package->encode_expectations)[pos];
747
748        switch (do_encode_custom(expected, &test_custom_data[i], package)) {
749        case -1:
750            if (expected->success) {
751                TEST_error("Failed custom encode round trip %u of %s",
752                           i, package->name);
753                TEST_openssl_errors();
754                fail++;
755            }
756            break;
757        case 0:
758            TEST_error("Custom encode round trip %u of %s mismatch",
759                       i, package->name);
760            TEST_openssl_errors();
761            fail++;
762            break;
763        case 1:
764            break;
765        default:
766            OPENSSL_die("do_encode_custom() return unknown value",
767                        __FILE__, __LINE__);
768        }
769        switch (do_decode_custom(&test_custom_data[i], expected,
770                                 package->encode_expectations_elem_size,
771                                 package)) {
772        case -1:
773            if (expected->success) {
774                TEST_error("Failed custom decode round trip %u of %s",
775                           i, package->name);
776                TEST_openssl_errors();
777                fail++;
778            }
779            break;
780        case 0:
781            TEST_error("Custom decode round trip %u of %s mismatch",
782                       i, package->name);
783            TEST_openssl_errors();
784            fail++;
785            break;
786        case 1:
787            break;
788        default:
789            OPENSSL_die("do_decode_custom() return unknown value",
790                        __FILE__, __LINE__);
791        }
792    }
793
794    /* Do enc_dec checks */
795    nelems = package->encdec_data_size / package->encdec_data_elem_size;
796    for (i = 0; i < nelems; i++) {
797        size_t pos = i * package->encdec_data_elem_size;
798        EXPECTED *expected
799            = (EXPECTED *)&((unsigned char *)package->encdec_data)[pos];
800
801        switch (do_enc_dec(expected, package->encdec_data_elem_size, package)) {
802        case -1:
803            if (expected->success) {
804                TEST_error("Failed encode/decode round trip %u of %s",
805                           i, package->name);
806                TEST_openssl_errors();
807                fail++;
808            }
809            break;
810        case 0:
811            TEST_error("Encode/decode round trip %u of %s mismatch",
812                       i, package->name);
813            fail++;
814            break;
815        case 1:
816            break;
817        default:
818            OPENSSL_die("do_enc_dec() return unknown value",
819                        __FILE__, __LINE__);
820        }
821    }
822
823    if (!do_print_item(package)) {
824        TEST_error("Printing of %s failed", package->name);
825        TEST_openssl_errors();
826        fail++;
827    }
828
829    return fail == 0;
830}
831
832#ifndef OPENSSL_NO_DEPRECATED_3_0
833static int test_long_32bit(void)
834{
835    return test_intern(&long_test_package_32bit);
836}
837
838static int test_long_64bit(void)
839{
840    return test_intern(&long_test_package_64bit);
841}
842#endif
843
844static int test_int32(void)
845{
846    return test_intern(&int32_test_package);
847}
848
849static int test_uint32(void)
850{
851    return test_intern(&uint32_test_package);
852}
853
854static int test_int64(void)
855{
856    return test_intern(&int64_test_package);
857}
858
859static int test_uint64(void)
860{
861    return test_intern(&uint64_test_package);
862}
863
864typedef struct {
865    ASN1_STRING *invalidDirString;
866} INVALIDTEMPLATE;
867
868ASN1_SEQUENCE(INVALIDTEMPLATE) = {
869    /*
870     * DirectoryString is a CHOICE type so it must use explicit tagging -
871     * but we deliberately use implicit here, which makes this template invalid.
872     */
873    ASN1_IMP(INVALIDTEMPLATE, invalidDirString, DIRECTORYSTRING, 12)
874} static_ASN1_SEQUENCE_END(INVALIDTEMPLATE)
875
876IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(INVALIDTEMPLATE)
877IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(INVALIDTEMPLATE)
878
879static int test_invalid_template(void)
880{
881    INVALIDTEMPLATE *temp = INVALIDTEMPLATE_new();
882    int ret;
883
884    if (!TEST_ptr(temp))
885        return 0;
886
887    ret = i2d_INVALIDTEMPLATE(temp, NULL);
888
889    INVALIDTEMPLATE_free(temp);
890
891    /* We expect the i2d operation to fail */
892    return ret < 0;
893}
894
895
896int setup_tests(void)
897{
898#ifndef OPENSSL_NO_DEPRECATED_3_0
899    ADD_TEST(test_long_32bit);
900    ADD_TEST(test_long_64bit);
901#endif
902    ADD_TEST(test_int32);
903    ADD_TEST(test_uint32);
904    ADD_TEST(test_int64);
905    ADD_TEST(test_uint64);
906    ADD_TEST(test_invalid_template);
907    return 1;
908}
909