xref: /src/crypto/openssl/test/asn1_decode_test.c (revision f25b8c9fb4f58cf61adb47d7570abe7caa6d385d)
1 /*
2  * Copyright 2017-2024 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/asn1.h>
15 #include <openssl/asn1t.h>
16 #include <openssl/obj_mac.h>
17 #include "internal/numbers.h"
18 #include "testutil.h"
19 
20 #ifdef __GNUC__
21 #pragma GCC diagnostic ignored "-Wunused-function"
22 #endif
23 #ifdef __clang__
24 #pragma clang diagnostic ignored "-Wunused-function"
25 #endif
26 
27 /* Badly coded ASN.1 INTEGER zero wrapped in a sequence */
28 static unsigned char t_invalid_zero[] = {
29     0x30, 0x02, /* SEQUENCE tag + length */
30     0x02, 0x00 /* INTEGER tag + length */
31 };
32 
33 #ifndef OPENSSL_NO_DEPRECATED_3_0
34 /* LONG case ************************************************************* */
35 
36 typedef struct {
37     long test_long;
38 } ASN1_LONG_DATA;
39 
40 ASN1_SEQUENCE(ASN1_LONG_DATA) = {
41     ASN1_EMBED(ASN1_LONG_DATA, test_long, LONG),
42 } static_ASN1_SEQUENCE_END(ASN1_LONG_DATA)
43 
44     IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_LONG_DATA)
45 IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_LONG_DATA)
46 
47 static int test_long(void)
48 {
49     const unsigned char *p = t_invalid_zero;
50     ASN1_LONG_DATA *dectst = d2i_ASN1_LONG_DATA(NULL, &p, sizeof(t_invalid_zero));
51 
52     if (dectst == NULL)
53         return 0; /* Fail */
54 
55     ASN1_LONG_DATA_free(dectst);
56     return 1;
57 }
58 #endif
59 
60 /* INT32 case ************************************************************* */
61 
62 typedef struct {
63     int32_t test_int32;
64 } ASN1_INT32_DATA;
65 
66 ASN1_SEQUENCE(ASN1_INT32_DATA) = {
67     ASN1_EMBED(ASN1_INT32_DATA, test_int32, INT32),
68 } static_ASN1_SEQUENCE_END(ASN1_INT32_DATA)
69 
70     IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_INT32_DATA)
71 IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_INT32_DATA)
72 
73 static int test_int32(void)
74 {
75     const unsigned char *p = t_invalid_zero;
76     ASN1_INT32_DATA *dectst = d2i_ASN1_INT32_DATA(NULL, &p, sizeof(t_invalid_zero));
77 
78     if (dectst == NULL)
79         return 0; /* Fail */
80 
81     ASN1_INT32_DATA_free(dectst);
82     return 1;
83 }
84 
85 /* UINT32 case ************************************************************* */
86 
87 typedef struct {
88     uint32_t test_uint32;
89 } ASN1_UINT32_DATA;
90 
91 ASN1_SEQUENCE(ASN1_UINT32_DATA) = {
92     ASN1_EMBED(ASN1_UINT32_DATA, test_uint32, UINT32),
93 } static_ASN1_SEQUENCE_END(ASN1_UINT32_DATA)
94 
95     IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_UINT32_DATA)
96 IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_UINT32_DATA)
97 
98 static int test_uint32(void)
99 {
100     const unsigned char *p = t_invalid_zero;
101     ASN1_UINT32_DATA *dectst = d2i_ASN1_UINT32_DATA(NULL, &p, sizeof(t_invalid_zero));
102 
103     if (dectst == NULL)
104         return 0; /* Fail */
105 
106     ASN1_UINT32_DATA_free(dectst);
107     return 1;
108 }
109 
110 /* INT64 case ************************************************************* */
111 
112 typedef struct {
113     int64_t test_int64;
114 } ASN1_INT64_DATA;
115 
116 ASN1_SEQUENCE(ASN1_INT64_DATA) = {
117     ASN1_EMBED(ASN1_INT64_DATA, test_int64, INT64),
118 } static_ASN1_SEQUENCE_END(ASN1_INT64_DATA)
119 
120     IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_INT64_DATA)
121 IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_INT64_DATA)
122 
123 static int test_int64(void)
124 {
125     const unsigned char *p = t_invalid_zero;
126     ASN1_INT64_DATA *dectst = d2i_ASN1_INT64_DATA(NULL, &p, sizeof(t_invalid_zero));
127 
128     if (dectst == NULL)
129         return 0; /* Fail */
130 
131     ASN1_INT64_DATA_free(dectst);
132     return 1;
133 }
134 
135 /* UINT64 case ************************************************************* */
136 
137 typedef struct {
138     uint64_t test_uint64;
139 } ASN1_UINT64_DATA;
140 
141 ASN1_SEQUENCE(ASN1_UINT64_DATA) = {
142     ASN1_EMBED(ASN1_UINT64_DATA, test_uint64, UINT64),
143 } static_ASN1_SEQUENCE_END(ASN1_UINT64_DATA)
144 
145     IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_UINT64_DATA)
146 IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_UINT64_DATA)
147 
148 static int test_uint64(void)
149 {
150     const unsigned char *p = t_invalid_zero;
151     ASN1_UINT64_DATA *dectst = d2i_ASN1_UINT64_DATA(NULL, &p, sizeof(t_invalid_zero));
152 
153     if (dectst == NULL)
154         return 0; /* Fail */
155 
156     ASN1_UINT64_DATA_free(dectst);
157     return 1;
158 }
159 
160 /* GeneralizedTime underflow *********************************************** */
161 
test_gentime(void)162 static int test_gentime(void)
163 {
164     /* Underflowing GeneralizedTime 161208193400Z (YYMMDDHHMMSSZ) */
165     const unsigned char der[] = {
166         0x18,
167         0x0d,
168         0x31,
169         0x36,
170         0x31,
171         0x32,
172         0x30,
173         0x38,
174         0x31,
175         0x39,
176         0x33,
177         0x34,
178         0x30,
179         0x30,
180         0x5a,
181     };
182     const unsigned char *p;
183     int der_len, rc = 1;
184     ASN1_GENERALIZEDTIME *gentime;
185 
186     p = der;
187     der_len = sizeof(der);
188     gentime = d2i_ASN1_GENERALIZEDTIME(NULL, &p, der_len);
189 
190     if (!TEST_ptr_null(gentime))
191         rc = 0; /* fail */
192 
193     ASN1_GENERALIZEDTIME_free(gentime);
194     return rc;
195 }
196 
197 /* UTCTime underflow ******************************************************* */
198 
test_utctime(void)199 static int test_utctime(void)
200 {
201     /* Underflowing UTCTime 0205104700Z (MMDDHHMMSSZ) */
202     const unsigned char der[] = {
203         0x17,
204         0x0b,
205         0x30,
206         0x32,
207         0x30,
208         0x35,
209         0x31,
210         0x30,
211         0x34,
212         0x37,
213         0x30,
214         0x30,
215         0x5a,
216     };
217     const unsigned char *p;
218     int der_len, rc = 1;
219     ASN1_UTCTIME *utctime;
220 
221     p = der;
222     der_len = sizeof(der);
223     utctime = d2i_ASN1_UTCTIME(NULL, &p, der_len);
224 
225     if (!TEST_ptr_null(utctime))
226         rc = 0; /* fail */
227 
228     ASN1_UTCTIME_free(utctime);
229     return rc;
230 }
231 
232 /* Invalid template ******************************************************** */
233 
234 typedef struct {
235     ASN1_STRING *invalidDirString;
236 } INVALIDTEMPLATE;
237 
238 ASN1_SEQUENCE(INVALIDTEMPLATE) = {
239     /*
240      * DirectoryString is a CHOICE type so it must use explicit tagging -
241      * but we deliberately use implicit here, which makes this template invalid.
242      */
243     ASN1_IMP(INVALIDTEMPLATE, invalidDirString, DIRECTORYSTRING, 12)
244 } static_ASN1_SEQUENCE_END(INVALIDTEMPLATE)
245 
246     IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(INVALIDTEMPLATE)
247 IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(INVALIDTEMPLATE)
248 
249 /* Empty sequence for invalid template test */
250 static unsigned char t_invalid_template[] = {
251     0x30, 0x03, /* SEQUENCE tag + length */
252     0x0c, 0x01, 0x41 /* UTF8String, length 1, "A" */
253 };
254 
test_invalid_template(void)255 static int test_invalid_template(void)
256 {
257     const unsigned char *p = t_invalid_template;
258     INVALIDTEMPLATE *tmp = d2i_INVALIDTEMPLATE(NULL, &p,
259         sizeof(t_invalid_template));
260 
261     /* We expect a NULL pointer return */
262     if (TEST_ptr_null(tmp))
263         return 1;
264 
265     INVALIDTEMPLATE_free(tmp);
266     return 0;
267 }
268 
test_reuse_asn1_object(void)269 static int test_reuse_asn1_object(void)
270 {
271     static unsigned char cn_der[] = { 0x06, 0x03, 0x55, 0x04, 0x06 };
272     static unsigned char oid_der[] = {
273         0x06, 0x06, 0x2a, 0x03, 0x04, 0x05, 0x06, 0x07
274     };
275     int ret = 0;
276     ASN1_OBJECT *obj;
277     unsigned char const *p = oid_der;
278 
279     /* Create an object that owns dynamically allocated 'sn' and 'ln' fields */
280 
281     if (!TEST_ptr(obj = ASN1_OBJECT_create(NID_undef, cn_der, sizeof(cn_der),
282                       "C", "countryName")))
283         goto err;
284     /* reuse obj - this should not leak sn and ln */
285     if (!TEST_ptr(d2i_ASN1_OBJECT(&obj, &p, sizeof(oid_der))))
286         goto err;
287     ret = 1;
288 err:
289     ASN1_OBJECT_free(obj);
290     return ret;
291 }
292 
setup_tests(void)293 int setup_tests(void)
294 {
295 #ifndef OPENSSL_NO_DEPRECATED_3_0
296     ADD_TEST(test_long);
297 #endif
298     ADD_TEST(test_int32);
299     ADD_TEST(test_uint32);
300     ADD_TEST(test_int64);
301     ADD_TEST(test_uint64);
302     ADD_TEST(test_gentime);
303     ADD_TEST(test_utctime);
304     ADD_TEST(test_invalid_template);
305     ADD_TEST(test_reuse_asn1_object);
306     return 1;
307 }
308