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>