[BACK]Return to gen_decode.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / asn1_compile

Annotation of src/usr.bin/asn1_compile/gen_decode.c, Revision 1.1

1.1     ! hin         1: /*
        !             2:  * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
        !             3:  * (Royal Institute of Technology, Stockholm, Sweden).
        !             4:  * All rights reserved.
        !             5:  *
        !             6:  * Redistribution and use in source and binary forms, with or without
        !             7:  * modification, are permitted provided that the following conditions
        !             8:  * are met:
        !             9:  *
        !            10:  * 1. Redistributions of source code must retain the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer.
        !            12:  *
        !            13:  * 2. Redistributions in binary form must reproduce the above copyright
        !            14:  *    notice, this list of conditions and the following disclaimer in the
        !            15:  *    documentation and/or other materials provided with the distribution.
        !            16:  *
        !            17:  * 3. Neither the name of the Institute nor the names of its contributors
        !            18:  *    may be used to endorse or promote products derived from this software
        !            19:  *    without specific prior written permission.
        !            20:  *
        !            21:  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
        !            22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
        !            25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            31:  * SUCH DAMAGE.
        !            32:  */
        !            33:
        !            34: #include "gen_locl.h"
        !            35:
        !            36: /*
        !            37: RCSID("$KTH: gen_decode.c,v 1.18 2002/08/09 15:37:34 joda Exp $");
        !            38: */
        !            39:
        !            40: static void
        !            41: decode_primitive (const char *typename, const char *name)
        !            42: {
        !            43:     fprintf (codefile,
        !            44:             "e = decode_%s(p, len, %s, &l);\n"
        !            45:             "FORW;\n",
        !            46:             typename,
        !            47:             name);
        !            48: }
        !            49:
        !            50: static void
        !            51: decode_type (const char *name, const Type *t)
        !            52: {
        !            53:     switch (t->type) {
        !            54:     case TType:
        !            55: #if 0
        !            56:        decode_type (name, t->symbol->type);
        !            57: #endif
        !            58:        fprintf (codefile,
        !            59:                 "e = decode_%s(p, len, %s, &l);\n"
        !            60:                 "FORW;\n",
        !            61:                 t->symbol->gen_name, name);
        !            62:        break;
        !            63:     case TInteger:
        !            64:        if(t->members == NULL)
        !            65:            decode_primitive ("integer", name);
        !            66:        else {
        !            67:            char *s;
        !            68:            asprintf(&s, "(int*)%s", name);
        !            69:            if(s == NULL)
        !            70:                errx (1, "out of memory");
        !            71:            decode_primitive ("integer", s);
        !            72:            free(s);
        !            73:        }
        !            74:        break;
        !            75:     case TUInteger:
        !            76:        decode_primitive ("unsigned", name);
        !            77:        break;
        !            78:     case TEnumerated:
        !            79:        decode_primitive ("enumerated", name);
        !            80:        break;
        !            81:     case TOctetString:
        !            82:        decode_primitive ("octet_string", name);
        !            83:        break;
        !            84:     case TOID :
        !            85:        decode_primitive ("oid", name);
        !            86:        break;
        !            87:     case TBitString: {
        !            88:        Member *m;
        !            89:        int tag = -1;
        !            90:        int pos;
        !            91:
        !            92:        fprintf (codefile,
        !            93:                 "e = der_match_tag_and_length (p, len, UNIV, PRIM, UT_BitString,"
        !            94:                 "&reallen, &l);\n"
        !            95:                 "FORW;\n"
        !            96:                 "if(len < reallen)\n"
        !            97:                 "return ASN1_OVERRUN;\n"
        !            98:                 "p++;\n"
        !            99:                 "len--;\n"
        !           100:                 "reallen--;\n"
        !           101:                 "ret++;\n");
        !           102:        pos = 0;
        !           103:        for (m = t->members; m && tag != m->val; m = m->next) {
        !           104:            while (m->val / 8 > pos / 8) {
        !           105:                fprintf (codefile,
        !           106:                         "p++; len--; reallen--; ret++;\n");
        !           107:                pos += 8;
        !           108:            }
        !           109:            fprintf (codefile,
        !           110:                     "%s->%s = (*p >> %d) & 1;\n",
        !           111:                     name, m->gen_name, 7 - m->val % 8);
        !           112:            if (tag == -1)
        !           113:                tag = m->val;
        !           114:        }
        !           115:        fprintf (codefile,
        !           116:                 "p += reallen; len -= reallen; ret += reallen;\n");
        !           117:        break;
        !           118:     }
        !           119:     case TSequence: {
        !           120:        Member *m;
        !           121:        int tag = -1;
        !           122:
        !           123:        if (t->members == NULL)
        !           124:            break;
        !           125:
        !           126:        fprintf (codefile,
        !           127:                 "e = der_match_tag_and_length (p, len, UNIV, CONS, UT_Sequence,"
        !           128:                 "&reallen, &l);\n"
        !           129:                 "FORW;\n"
        !           130:                 "{\n"
        !           131:                 "int dce_fix;\n"
        !           132:                 "if((dce_fix = fix_dce(reallen, &len)) < 0)\n"
        !           133:                 "return ASN1_BAD_FORMAT;\n");
        !           134:
        !           135:        for (m = t->members; m && tag != m->val; m = m->next) {
        !           136:            char *s;
        !           137:
        !           138:            asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name);
        !           139:            if (0 && m->type->type == TType){
        !           140:                if(m->optional)
        !           141:                    fprintf (codefile,
        !           142:                             "%s = malloc(sizeof(*%s));\n"
        !           143:                             "if(%s == NULL) return ENOMEM;\n", s, s, s);
        !           144:                fprintf (codefile,
        !           145:                         "e = decode_seq_%s(p, len, %d, %d, %s, &l);\n",
        !           146:                         m->type->symbol->gen_name,
        !           147:                         m->val,
        !           148:                         m->optional,
        !           149:                         s);
        !           150:                if(m->optional)
        !           151:                    fprintf (codefile,
        !           152:                             "if (e == ASN1_MISSING_FIELD) {\n"
        !           153:                             "free(%s);\n"
        !           154:                             "%s = NULL;\n"
        !           155:                             "e = l = 0;\n"
        !           156:                             "}\n",
        !           157:                             s, s);
        !           158:
        !           159:                fprintf (codefile, "FORW;\n");
        !           160:
        !           161:            }else{
        !           162:                fprintf (codefile, "{\n"
        !           163:                         "size_t newlen, oldlen;\n\n"
        !           164:                         "e = der_match_tag (p, len, CONTEXT, CONS, %d, &l);\n",
        !           165:                         m->val);
        !           166:                fprintf (codefile,
        !           167:                         "if (e)\n");
        !           168:                if(m->optional)
        !           169:                    /* XXX should look at e */
        !           170:                    fprintf (codefile,
        !           171:                             "%s = NULL;\n", s);
        !           172:                else
        !           173:                    fprintf (codefile,
        !           174:                             "return e;\n");
        !           175:                fprintf (codefile,
        !           176:                         "else {\n");
        !           177:                fprintf (codefile,
        !           178:                         "p += l;\n"
        !           179:                         "len -= l;\n"
        !           180:                         "ret += l;\n"
        !           181:                         "e = der_get_length (p, len, &newlen, &l);\n"
        !           182:                         "FORW;\n"
        !           183:                         "{\n"
        !           184:
        !           185:                         "int dce_fix;\n"
        !           186:                         "oldlen = len;\n"
        !           187:                         "if((dce_fix = fix_dce(newlen, &len)) < 0)"
        !           188:                         "return ASN1_BAD_FORMAT;\n");
        !           189:                if (m->optional)
        !           190:                    fprintf (codefile,
        !           191:                             "%s = malloc(sizeof(*%s));\n"
        !           192:                             "if(%s == NULL) return ENOMEM;\n", s, s, s);
        !           193:                decode_type (s, m->type);
        !           194:                fprintf (codefile,
        !           195:                         "if(dce_fix){\n"
        !           196:                         "e = der_match_tag_and_length (p, len, "
        !           197:                         "(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
        !           198:                         "FORW;\n"
        !           199:                         "}else \n"
        !           200:                         "len = oldlen - newlen;\n"
        !           201:                         "}\n"
        !           202:                         "}\n");
        !           203:                fprintf (codefile,
        !           204:                         "}\n");
        !           205:            }
        !           206:            if (tag == -1)
        !           207:                tag = m->val;
        !           208:            free (s);
        !           209:        }
        !           210:        fprintf(codefile,
        !           211:                "if(dce_fix){\n"
        !           212:                "e = der_match_tag_and_length (p, len, "
        !           213:                "(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
        !           214:                "FORW;\n"
        !           215:                "}\n"
        !           216:                "}\n");
        !           217:
        !           218:        break;
        !           219:     }
        !           220:     case TSequenceOf: {
        !           221:        char *n;
        !           222:
        !           223:        fprintf (codefile,
        !           224:                 "e = der_match_tag_and_length (p, len, UNIV, CONS, UT_Sequence,"
        !           225:                 "&reallen, &l);\n"
        !           226:                 "FORW;\n"
        !           227:                 "if(len < reallen)\n"
        !           228:                 "return ASN1_OVERRUN;\n"
        !           229:                 "len = reallen;\n");
        !           230:
        !           231:        fprintf (codefile,
        !           232:                 "{\n"
        !           233:                 "size_t origlen = len;\n"
        !           234:                 "int oldret = ret;\n"
        !           235:                 "ret = 0;\n"
        !           236:                 "(%s)->len = 0;\n"
        !           237:                 "(%s)->val = NULL;\n"
        !           238:                 "while(ret < origlen) {\n"
        !           239:                 "(%s)->len++;\n"
        !           240:                 "(%s)->val = realloc((%s)->val, sizeof(*((%s)->val)) * (%s)->len);\n",
        !           241:                 name, name, name, name, name, name, name);
        !           242:        asprintf (&n, "&(%s)->val[(%s)->len-1]", name, name);
        !           243:        decode_type (n, t->subtype);
        !           244:        fprintf (codefile,
        !           245:                 "len = origlen - ret;\n"
        !           246:                 "}\n"
        !           247:                 "ret += oldret;\n"
        !           248:                 "}\n");
        !           249:        free (n);
        !           250:        break;
        !           251:     }
        !           252:     case TGeneralizedTime:
        !           253:        decode_primitive ("generalized_time", name);
        !           254:        break;
        !           255:     case TGeneralString:
        !           256:        decode_primitive ("general_string", name);
        !           257:        break;
        !           258:     case TApplication:
        !           259:        fprintf (codefile,
        !           260:                 "e = der_match_tag_and_length (p, len, APPL, CONS, %d, "
        !           261:                 "&reallen, &l);\n"
        !           262:                 "FORW;\n"
        !           263:                 "{\n"
        !           264:                 "int dce_fix;\n"
        !           265:                 "if((dce_fix = fix_dce(reallen, &len)) < 0)\n"
        !           266:                 "return ASN1_BAD_FORMAT;\n",
        !           267:                 t->application);
        !           268:        decode_type (name, t->subtype);
        !           269:        fprintf(codefile,
        !           270:                "if(dce_fix){\n"
        !           271:                "e = der_match_tag_and_length (p, len, "
        !           272:                "(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
        !           273:                "FORW;\n"
        !           274:                "}\n"
        !           275:                "}\n");
        !           276:
        !           277:        break;
        !           278:     default :
        !           279:        abort ();
        !           280:     }
        !           281: }
        !           282:
        !           283: void
        !           284: generate_type_decode (const Symbol *s)
        !           285: {
        !           286:   fprintf (headerfile,
        !           287:           "int    "
        !           288:           "decode_%s(const unsigned char *, size_t, %s *, size_t *);\n",
        !           289:           s->gen_name, s->gen_name);
        !           290:
        !           291:   fprintf (codefile, "#define FORW "
        !           292:           "if(e) goto fail; "
        !           293:           "p += l; "
        !           294:           "len -= l; "
        !           295:           "ret += l\n\n");
        !           296:
        !           297:
        !           298:   fprintf (codefile, "int\n"
        !           299:           "decode_%s(const unsigned char *p,"
        !           300:           " size_t len, %s *data, size_t *size)\n"
        !           301:           "{\n",
        !           302:           s->gen_name, s->gen_name);
        !           303:
        !           304:   switch (s->type->type) {
        !           305:   case TInteger:
        !           306:   case TUInteger:
        !           307:   case TOctetString:
        !           308:   case TOID:
        !           309:   case TGeneralizedTime:
        !           310:   case TGeneralString:
        !           311:   case TBitString:
        !           312:   case TSequence:
        !           313:   case TSequenceOf:
        !           314:   case TApplication:
        !           315:   case TType:
        !           316:     fprintf (codefile,
        !           317:             "size_t ret = 0, reallen;\n"
        !           318:             "size_t l;\n"
        !           319:             "int e;\n\n");
        !           320:     fprintf (codefile, "memset(data, 0, sizeof(*data));\n");
        !           321:     fprintf (codefile, "reallen = 0;\n"); /* hack to avoid `unused variable' */
        !           322:
        !           323:     decode_type ("data", s->type);
        !           324:     fprintf (codefile,
        !           325:             "if(size) *size = ret;\n"
        !           326:             "return 0;\n");
        !           327:     fprintf (codefile,
        !           328:             "fail:\n"
        !           329:             "free_%s(data);\n"
        !           330:             "return e;\n",
        !           331:             s->gen_name);
        !           332:     break;
        !           333:   default:
        !           334:     abort ();
        !           335:   }
        !           336:   fprintf (codefile, "}\n\n");
        !           337: }
        !           338:
        !           339: void
        !           340: generate_seq_type_decode (const Symbol *s)
        !           341: {
        !           342:     fprintf (headerfile,
        !           343:             "int decode_seq_%s(const unsigned char *, size_t, int, int, "
        !           344:             "%s *, size_t *);\n",
        !           345:             s->gen_name, s->gen_name);
        !           346:
        !           347:     fprintf (codefile, "int\n"
        !           348:             "decode_seq_%s(const unsigned char *p, size_t len, int tag, "
        !           349:             "int optional, %s *data, size_t *size)\n"
        !           350:             "{\n",
        !           351:             s->gen_name, s->gen_name);
        !           352:
        !           353:     fprintf (codefile,
        !           354:             "size_t newlen, oldlen;\n"
        !           355:             "size_t l, ret = 0;\n"
        !           356:             "int e;\n"
        !           357:             "int dce_fix;\n");
        !           358:
        !           359:     fprintf (codefile,
        !           360:             "e = der_match_tag(p, len, CONTEXT, CONS, tag, &l);\n"
        !           361:             "if (e)\n"
        !           362:             "return e;\n");
        !           363:     fprintf (codefile,
        !           364:             "p += l;\n"
        !           365:             "len -= l;\n"
        !           366:             "ret += l;\n"
        !           367:             "e = der_get_length(p, len, &newlen, &l);\n"
        !           368:             "if (e)\n"
        !           369:             "return e;\n"
        !           370:             "p += l;\n"
        !           371:             "len -= l;\n"
        !           372:             "ret += l;\n"
        !           373:             "oldlen = len;\n"
        !           374:             "if ((dce_fix = fix_dce(newlen, &len)) < 0)\n"
        !           375:             "return ASN1_BAD_FORMAT;\n"
        !           376:             "e = decode_%s(p, len, data, &l);\n"
        !           377:             "if (e)\n"
        !           378:             "return e;\n"
        !           379:             "p += l;\n"
        !           380:             "len -= l;\n"
        !           381:             "ret += l;\n"
        !           382:             "if (dce_fix) {\n"
        !           383:             "size_t reallen;\n\n"
        !           384:             "e = der_match_tag_and_length(p, len, "
        !           385:             "(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
        !           386:             "if (e)\n"
        !           387:             "return e;\n"
        !           388:             "ret += l;\n"
        !           389:             "}\n",
        !           390:             s->gen_name);
        !           391:     fprintf (codefile,
        !           392:             "if(size) *size = ret;\n"
        !           393:             "return 0;\n");
        !           394:
        !           395:     fprintf (codefile, "}\n\n");
        !           396: }