Annotation of embedaddon/strongswan/src/libstrongswan/tests/suites/test_asn1_parser.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2014-2017 Andreas Steffen
3: * HSR Hochschule fuer Technik Rapperswil
4: *
5: * This program is free software; you can redistribute it and/or modify it
6: * under the terms of the GNU General Public License as published by the
7: * Free Software Foundation; either version 2 of the License, or (at your
8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9: *
10: * This program is distributed in the hope that it will be useful, but
11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13: * for more details.
14: */
15:
16: #include "test_suite.h"
17:
18: #include <asn1/asn1_parser.h>
19: #include <utils/chunk.h>
20:
21: /*******************************************************************************
22: * utilities
23: */
24:
25: typedef struct {
26: bool success;
27: int count;
28: chunk_t blob;
29: } asn1_test_t;
30:
31: static void run_parser_test(const asn1Object_t *objects, int id,
32: asn1_test_t *test)
33: {
34: asn1_parser_t *parser;
35: chunk_t object;
36: int objectID, count = 0;
37: bool success;
38:
39: parser = asn1_parser_create(objects, test->blob);
40: while (parser->iterate(parser, &objectID, &object))
41: {
42: if (objectID == id)
43: {
44: count++;
45: }
46: }
47: success = parser->success(parser);
48: parser->destroy(parser);
49:
50: ck_assert(success == test->success && count == test->count);
51: }
52:
53: /*******************************************************************************
54: * length
55: */
56:
57: static const asn1Object_t octetStringObjects[] = {
58: { 0, "octetString", ASN1_OCTET_STRING, ASN1_BODY }, /* 0 */
59: { 0, "exit", ASN1_EOC, ASN1_EXIT }
60: };
61:
62: asn1_test_t length_tests[] = {
63: { FALSE, 0, { NULL, 0 } },
64: { FALSE, 0, chunk_from_chars(0x04) },
65: { TRUE, 1, chunk_from_chars(0x04, 0x00) },
66: { TRUE, 1, chunk_from_chars(0x04, 0x01, 0xaa) },
67: { FALSE, 0, chunk_from_chars(0x04, 0x7f) },
68: { FALSE, 0, chunk_from_chars(0x04, 0x80) },
69: { FALSE, 0, chunk_from_chars(0x04, 0x81) },
70: { TRUE, 1, chunk_from_chars(0x04, 0x81, 0x00) },
71: { FALSE, 0, chunk_from_chars(0x04, 0x81, 0x01) },
72: { TRUE, 1, chunk_from_chars(0x04, 0x81, 0x01, 0xaa) },
73: { FALSE, 0, chunk_from_chars(0x04, 0x82, 0x00, 0x01) },
74: { TRUE, 1, chunk_from_chars(0x04, 0x82, 0x00, 0x01, 0xaa) },
75: { FALSE, 0, chunk_from_chars(0x04, 0x83, 0x00, 0x00, 0x01) },
76: { TRUE, 1, chunk_from_chars(0x04, 0x83, 0x00, 0x00, 0x01, 0xaa) },
77: { FALSE, 0, chunk_from_chars(0x04, 0x84, 0x00, 0x00, 0x00, 0x01) },
78: { TRUE, 1, chunk_from_chars(0x04, 0x84, 0x00, 0x00, 0x00, 0x01, 0xaa) },
79: };
80:
81: START_TEST(test_asn1_parser_length)
82: {
83: run_parser_test(octetStringObjects, 0, &length_tests[_i]);
84: }
85: END_TEST
86:
87: /*******************************************************************************
88: * loop
89: */
90:
91: static const asn1Object_t loopObjects[] = {
92: { 0, "loopObjects", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
93: { 1, "octetString", ASN1_OCTET_STRING, ASN1_BODY }, /* 1 */
94: { 0, "end loop", ASN1_EOC, ASN1_END }, /* 2 */
95: { 0, "exit", ASN1_EOC, ASN1_EXIT }
96: };
97:
98: asn1_test_t loop_tests[] = {
99: { TRUE, 0, chunk_from_chars(0x30, 0x00) },
100: { FALSE, 0, chunk_from_chars(0x30, 0x02, 0x04, 0x01) },
101: { TRUE, 1, chunk_from_chars(0x30, 0x03, 0x04, 0x01, 0xaa) },
102: { TRUE, 2, chunk_from_chars(0x30, 0x05, 0x04, 0x01, 0xaa, 0x04, 0x00) },
103: { FALSE, 1, chunk_from_chars(0x30, 0x05, 0x04, 0x01, 0xaa, 0x05, 0x00) },
104: { TRUE, 3, chunk_from_chars(0x30, 0x09, 0x04, 0x01, 0xaa, 0x04, 0x00,
105: 0x04, 0x02, 0xbb, 0xcc) },
106: };
107:
108: START_TEST(test_asn1_parser_loop)
109: {
110: run_parser_test(loopObjects, 1, &loop_tests[_i]);
111: }
112: END_TEST
113:
114: /*******************************************************************************
115: * default
116: */
117:
118: typedef struct {
119: int i1, i2, i3;
120: chunk_t blob;
121: } default_opt_test_t;
122:
123: static const asn1Object_t defaultObjects[] = {
124: { 0, "defaultObjects", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
125: { 1, "explicit int1", ASN1_CONTEXT_C_1, ASN1_DEF }, /* 1 */
126: { 2, "int1", ASN1_INTEGER, ASN1_BODY }, /* 2 */
127: { 1, "int2", ASN1_INTEGER, ASN1_DEF|ASN1_BODY }, /* 3 */
128: { 1, "implicit int3", ASN1_CONTEXT_S_3, ASN1_DEF|ASN1_BODY }, /* 4 */
129: { 0, "exit", ASN1_EOC, ASN1_EXIT }
130: };
131:
132: default_opt_test_t default_tests[] = {
133: { -1, -2, -3, chunk_from_chars(0x30, 0x00) },
134: { 1, -2, -3, chunk_from_chars(0x30, 0x05, 0xa1, 0x03, 0x02, 0x01, 0x01) },
135: { -1, 2, -3, chunk_from_chars(0x30, 0x03, 0x02, 0x01, 0x02) },
136: { -1, -2, 3, chunk_from_chars(0x30, 0x03, 0x83, 0x01, 0x03) },
137: { 1, 2, -3, chunk_from_chars(0x30, 0x08, 0xa1, 0x03, 0x02, 0x01, 0x01,
138: 0x02, 0x01, 0x02) },
139: { 1, -2, 3, chunk_from_chars(0x30, 0x08, 0xa1, 0x03, 0x02, 0x01, 0x01,
140: 0x83, 0x01, 0x03) },
141: { -1, 2, 3, chunk_from_chars(0x30, 0x06, 0x02, 0x01, 0x02,
142: 0x83, 0x01, 0x03) },
143: { 1, 2, 3, chunk_from_chars(0x30, 0x0b, 0xa1, 0x03, 0x02, 0x01, 0x01,
144: 0x02, 0x01, 0x02,
145: 0x83, 0x01, 0x03) },
146: { 0, 0, 0, chunk_from_chars(0x30, 0x0b, 0xa1, 0x03, 0x04, 0x01, 0xaa,
147: 0x02, 0x01, 0x02,
148: 0x83, 0x01, 0x03) },
149: { 1, 0, 0, chunk_from_chars(0x30, 0x0b, 0xa1, 0x03, 0x02, 0x01, 0x01,
150: 0x02, 0x05, 0x02,
151: 0x83, 0x01, 0x03) },
152: { 1, 2, 0, chunk_from_chars(0x30, 0x0b, 0xa1, 0x03, 0x02, 0x01, 0x01,
153: 0x02, 0x01, 0x02,
154: 0x83, 0x02, 0x03) },
155: };
156:
157: START_TEST(test_asn1_parser_default)
158: {
159: asn1_parser_t *parser;
160: chunk_t object;
161: int objectID, i1 = 0, i2 = 0, i3 = 0;
162: bool success;
163:
164: parser = asn1_parser_create(defaultObjects, default_tests[_i].blob);
165: while (parser->iterate(parser, &objectID, &object))
166: {
167: switch (objectID)
168: {
169: case 2:
170: i1 = object.len ? *object.ptr : -1;
171: break;
172: case 3:
173: i2 = object.len ? *object.ptr : -2;
174: break;
175: case 4:
176: i3 = object.len ? *object.ptr : -3;
177: break;
178: default:
179: break;
180: }
181: }
182: success = parser->success(parser);
183: parser->destroy(parser);
184:
185: ck_assert(success == (default_tests[_i].i1 &&
186: default_tests[_i].i2 &&
187: default_tests[_i].i3));
188:
189: ck_assert(i1 == default_tests[_i].i1 &&
190: i2 == default_tests[_i].i2 &&
191: i3 == default_tests[_i].i3);
192: }
193: END_TEST
194:
195: /*******************************************************************************
196: * option
197: */
198:
199: static const asn1Object_t optionObjects[] = {
200: { 0, "optionalObjects", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
201: { 1, "sequence int1", ASN1_SEQUENCE, ASN1_OPT }, /* 1 */
202: { 2, "int1", ASN1_INTEGER, ASN1_OPT|ASN1_BODY }, /* 2 */
203: { 2, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
204: { 1, "end opt", ASN1_EOC, ASN1_END }, /* 4 */
205: { 1, "int2", ASN1_INTEGER, ASN1_OPT|ASN1_BODY }, /* 5 */
206: { 1, "end opt", ASN1_EOC, ASN1_END }, /* 6 */
207: { 1, "implicit int3", ASN1_CONTEXT_S_3, ASN1_OPT|ASN1_BODY }, /* 7 */
208: { 1, "end opt", ASN1_EOC, ASN1_END }, /* 8 */
209: { 0, "exit", ASN1_EOC, ASN1_EXIT }
210: };
211:
212: default_opt_test_t option_tests[] = {
213: { 0, 0, 0, chunk_from_chars(0x30, 0x00) },
214: { 1, 0, 0, chunk_from_chars(0x30, 0x05, 0x30, 0x03, 0x02, 0x01, 0x01) },
215: { 0, 2, 0, chunk_from_chars(0x30, 0x03, 0x02, 0x01, 0x02) },
216: { 0, 0, 3, chunk_from_chars(0x30, 0x03, 0x83, 0x01, 0x03) },
217: { 1, 2, 0, chunk_from_chars(0x30, 0x08, 0x30, 0x03, 0x02, 0x01, 0x01,
218: 0x02, 0x01, 0x02) },
219: { 1, 0, 3, chunk_from_chars(0x30, 0x08, 0x30, 0x03, 0x02, 0x01, 0x01,
220: 0x83, 0x01, 0x03) },
221: { 0, 2, 3, chunk_from_chars(0x30, 0x06, 0x02, 0x01, 0x02,
222: 0x83, 0x01, 0x03) },
223: { 1, 2, 3, chunk_from_chars(0x30, 0x0b, 0x30, 0x03, 0x02, 0x01, 0x01,
224: 0x02, 0x01, 0x02,
225: 0x83, 0x01, 0x03) },
226: { 0, 2, 3, chunk_from_chars(0x30, 0x08, 0x30, 0x00,
227: 0x02, 0x01, 0x02,
228: 0x83, 0x01, 0x03) },
229: };
230:
231: START_TEST(test_asn1_parser_option)
232: {
233: asn1_parser_t *parser;
234: chunk_t object;
235: int objectID, i1 = 0, i2 = 0, i3 = 0;
236: bool success;
237:
238: parser = asn1_parser_create(optionObjects, option_tests[_i].blob);
239: while (parser->iterate(parser, &objectID, &object))
240: {
241: switch (objectID)
242: {
243: case 2:
244: i1 = *object.ptr;
245: break;
246: case 5:
247: i2 = *object.ptr;
248: break;
249: case 7:
250: i3 = *object.ptr;
251: break;
252: default:
253:
254: break;
255: }
256: }
257: success = parser->success(parser);
258: parser->destroy(parser);
259:
260: ck_assert(success);
261:
262: ck_assert(i1 == option_tests[_i].i1 &&
263: i2 == option_tests[_i].i2 &&
264: i3 == option_tests[_i].i3);
265: }
266: END_TEST
267:
268: /*******************************************************************************
269: * choice
270: */
271:
272: typedef struct {
273: int i1, i2, i3, i4;
274: chunk_t blob;
275: } choice_test_t;
276:
277: static const asn1Object_t choiceObjects[] = {
278: { 0, "choiceObject", ASN1_EOC, ASN1_CHOICE }, /* 0 */
279: { 1, "choiceA", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_CHOICE }, /* 1 */
280: { 2, "choice1", ASN1_OCTET_STRING, ASN1_OPT|ASN1_BODY }, /* 2 */
281: { 2, "end choice1", ASN1_EOC, ASN1_END|ASN1_CH }, /* 3 */
282: { 2, "choice2", ASN1_INTEGER, ASN1_OPT|ASN1_BODY }, /* 4 */
283: { 2, "end choice2", ASN1_EOC, ASN1_END|ASN1_CH }, /* 5 */
284: { 1, "end choiceA", ASN1_EOC, ASN1_END|ASN1_CHOICE|
285: ASN1_CH }, /* 6 */
286: { 1, "choiceB", ASN1_SEQUENCE, ASN1_OPT|ASN1_LOOP }, /* 7 */
287: { 2, "choiceObject", ASN1_EOC, ASN1_CHOICE }, /* 8 */
288: { 3, "choice3", ASN1_INTEGER, ASN1_OPT|ASN1_BODY }, /* 9 */
289: { 3, "end choice3", ASN1_EOC, ASN1_END|ASN1_CH }, /* 10 */
290: { 3, "choice4", ASN1_OCTET_STRING, ASN1_OPT|ASN1_BODY }, /* 11 */
291: { 3, "end choice4", ASN1_EOC, ASN1_END|ASN1_CH }, /* 12 */
292: { 2, "end choices", ASN1_EOC, ASN1_END|ASN1_CHOICE }, /* 13 */
293: { 1, "end loop/choice", ASN1_EOC, ASN1_END|ASN1_CH }, /* 14 */
294: { 0, "end choices", ASN1_EOC, ASN1_END|ASN1_CHOICE }, /* 15 */
295: { 0, "exit", ASN1_EOC, ASN1_EXIT }
296: };
297:
298: choice_test_t choice_tests[] = {
299: { 0, 0, 0, 0, { NULL, 0 } },
300: { 0, 0, 0, 0, chunk_from_chars(0xA0, 0x00) },
301: { 1, 0, 0, 0, chunk_from_chars(0xA0, 0x03, 0x04, 0x01, 0x01) },
302: { 1, 0, 0, 0, chunk_from_chars(0xA0, 0x06, 0x04, 0x01, 0x01,
303: 0x02, 0x01, 0x02) },
304: { 0, 2, 0, 0, chunk_from_chars(0xA0, 0x03, 0x02, 0x01, 0x02) },
305: { 0, 2, 0, 0, chunk_from_chars(0xA0, 0x03, 0x02, 0x01, 0x02,
306: 0x30, 0x03, 0x02, 0x01, 0x03) },
307: { 0, 0, 0, 0, chunk_from_chars(0xA0, 0x04, 0x03, 0x02, 0x00, 0x04) },
308: { 0, 0, 3, 0, chunk_from_chars(0x30, 0x03, 0x02, 0x01, 0x03) },
309: { 0, 0, 0, 4, chunk_from_chars(0x30, 0x03, 0x04, 0x01, 0x04) },
310: { 0, 0, 3, 4, chunk_from_chars(0x30, 0x06, 0x04, 0x01, 0x04,
311: 0x02, 0x01, 0x03) },
312: { 0, 0, 3, 4, chunk_from_chars(0x30, 0x06, 0x02, 0x01, 0x03,
313: 0x04, 0x01, 0x04) },
314: { 0, 0, 6, 0, chunk_from_chars(0x30, 0x06, 0x02, 0x01, 0x03,
315: 0x02, 0x01, 0x03) },
316: { 0, 0, 0, 8, chunk_from_chars(0x30, 0x06, 0x04, 0x01, 0x04,
317: 0x04, 0x01, 0x04) },
318: { 0, 0, 0, 0, chunk_from_chars(0x30, 0x04, 0x03, 0x02, 0x00, 0x04) },
319: { 0, 0, 0, 0, chunk_from_chars(0x03, 0x02, 0x00, 0x04) }
320: };
321:
322: START_TEST(test_asn1_parser_choice)
323: {
324: asn1_parser_t *parser;
325: chunk_t object;
326: int objectID, i1 = 0, i2 = 0, i3 = 0, i4 = 0;
327: bool success;
328:
329: parser = asn1_parser_create(choiceObjects, choice_tests[_i].blob);
330: while (parser->iterate(parser, &objectID, &object))
331: {
332: switch (objectID)
333: {
334: case 2:
335: i1 += *object.ptr;
336: break;
337: case 4:
338: i2 += *object.ptr;
339: break;
340: case 9:
341: i3 += *object.ptr;
342: break;
343: case 11:
344: i4 += *object.ptr;
345: break;
346: default:
347:
348: break;
349: }
350: }
351: success = parser->success(parser);
352: parser->destroy(parser);
353:
354: ck_assert(success == (choice_tests[_i].i1 ||
355: choice_tests[_i].i2 ||
356: choice_tests[_i].i3 ||
357: choice_tests[_i].i4 ));
358:
359: ck_assert(i1 == choice_tests[_i].i1 &&
360: i2 == choice_tests[_i].i2 &&
361: i3 == choice_tests[_i].i3 &&
362: i4 == choice_tests[_i].i4 );
363: }
364: END_TEST
365:
366:
367: Suite *asn1_parser_suite_create()
368: {
369: Suite *s;
370: TCase *tc;
371:
372: s = suite_create("asn1_parser");
373:
374: tc = tcase_create("length");
375: tcase_add_loop_test(tc, test_asn1_parser_length, 0, countof(length_tests));
376: suite_add_tcase(s, tc);
377:
378: tc = tcase_create("loop");
379: tcase_add_loop_test(tc, test_asn1_parser_loop, 0, countof(loop_tests));
380: suite_add_tcase(s, tc);
381:
382: tc = tcase_create("default");
383: tcase_add_loop_test(tc, test_asn1_parser_default, 0, countof(default_tests));
384: suite_add_tcase(s, tc);
385:
386: tc = tcase_create("option");
387: tcase_add_loop_test(tc, test_asn1_parser_option, 0, countof(option_tests));
388: suite_add_tcase(s, tc);
389:
390: tc = tcase_create("choice");
391: tcase_add_loop_test(tc, test_asn1_parser_choice, 0, countof(choice_tests));
392: suite_add_tcase(s, tc);
393:
394: return s;
395: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>