Path: blob/main/crypto/heimdal/lib/asn1/gen_copy.c
34879 views
/*1* Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan2* (Royal Institute of Technology, Stockholm, Sweden).3* All rights reserved.4*5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions7* are met:8*9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11*12* 2. Redistributions in binary form must reproduce the above copyright13* notice, this list of conditions and the following disclaimer in the14* documentation and/or other materials provided with the distribution.15*16* 3. Neither the name of the Institute nor the names of its contributors17* may be used to endorse or promote products derived from this software18* without specific prior written permission.19*20* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND21* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE22* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE23* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE24* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL25* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS26* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)27* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT28* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY29* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF30* SUCH DAMAGE.31*/3233#include "gen_locl.h"3435RCSID("$Id$");3637static int used_fail;3839static void40copy_primitive (const char *typename, const char *from, const char *to)41{42fprintf (codefile, "if(der_copy_%s(%s, %s)) goto fail;\n",43typename, from, to);44used_fail++;45}4647static void48copy_type (const char *from, const char *to, const Type *t, int preserve)49{50switch (t->type) {51case TType:52#if 053copy_type (from, to, t->symbol->type, preserve);54#endif55fprintf (codefile, "if(copy_%s(%s, %s)) goto fail;\n",56t->symbol->gen_name, from, to);57used_fail++;58break;59case TInteger:60if (t->range == NULL && t->members == NULL) {61copy_primitive ("heim_integer", from, to);62break;63}64case TBoolean:65case TEnumerated :66fprintf(codefile, "*(%s) = *(%s);\n", to, from);67break;68case TOctetString:69copy_primitive ("octet_string", from, to);70break;71case TBitString:72if (ASN1_TAILQ_EMPTY(t->members))73copy_primitive ("bit_string", from, to);74else75fprintf(codefile, "*(%s) = *(%s);\n", to, from);76break;77case TSet:78case TSequence:79case TChoice: {80Member *m, *have_ellipsis = NULL;8182if(t->members == NULL)83break;8485if ((t->type == TSequence || t->type == TChoice) && preserve) {86fprintf(codefile,87"{ int ret;\n"88"ret = der_copy_octet_string(&(%s)->_save, &(%s)->_save);\n"89"if (ret) goto fail;\n"90"}\n",91from, to);92used_fail++;93}9495if(t->type == TChoice) {96fprintf(codefile, "(%s)->element = (%s)->element;\n", to, from);97fprintf(codefile, "switch((%s)->element) {\n", from);98}99100ASN1_TAILQ_FOREACH(m, t->members, members) {101char *fs;102char *ts;103104if (m->ellipsis) {105have_ellipsis = m;106continue;107}108109if(t->type == TChoice)110fprintf(codefile, "case %s:\n", m->label);111112if (asprintf (&fs, "%s(%s)->%s%s",113m->optional ? "" : "&", from,114t->type == TChoice ? "u." : "", m->gen_name) < 0)115errx(1, "malloc");116if (fs == NULL)117errx(1, "malloc");118if (asprintf (&ts, "%s(%s)->%s%s",119m->optional ? "" : "&", to,120t->type == TChoice ? "u." : "", m->gen_name) < 0)121errx(1, "malloc");122if (ts == NULL)123errx(1, "malloc");124if(m->optional){125fprintf(codefile, "if(%s) {\n", fs);126fprintf(codefile, "%s = malloc(sizeof(*%s));\n", ts, ts);127fprintf(codefile, "if(%s == NULL) goto fail;\n", ts);128used_fail++;129}130copy_type (fs, ts, m->type, FALSE);131if(m->optional){132fprintf(codefile, "}else\n");133fprintf(codefile, "%s = NULL;\n", ts);134}135free (fs);136free (ts);137if(t->type == TChoice)138fprintf(codefile, "break;\n");139}140if(t->type == TChoice) {141if (have_ellipsis) {142fprintf(codefile, "case %s: {\n"143"int ret;\n"144"ret=der_copy_octet_string(&(%s)->u.%s, &(%s)->u.%s);\n"145"if (ret) goto fail;\n"146"break;\n"147"}\n",148have_ellipsis->label,149from, have_ellipsis->gen_name,150to, have_ellipsis->gen_name);151used_fail++;152}153fprintf(codefile, "}\n");154}155break;156}157case TSetOf:158case TSequenceOf: {159char *f = NULL, *T = NULL;160161fprintf (codefile, "if(((%s)->val = "162"malloc((%s)->len * sizeof(*(%s)->val))) == NULL && (%s)->len != 0)\n",163to, from, to, from);164fprintf (codefile, "goto fail;\n");165used_fail++;166fprintf(codefile,167"for((%s)->len = 0; (%s)->len < (%s)->len; (%s)->len++){\n",168to, to, from, to);169if (asprintf(&f, "&(%s)->val[(%s)->len]", from, to) < 0)170errx(1, "malloc");171if (f == NULL)172errx(1, "malloc");173if (asprintf(&T, "&(%s)->val[(%s)->len]", to, to) < 0)174errx(1, "malloc");175if (T == NULL)176errx(1, "malloc");177copy_type(f, T, t->subtype, FALSE);178fprintf(codefile, "}\n");179free(f);180free(T);181break;182}183case TGeneralizedTime:184fprintf(codefile, "*(%s) = *(%s);\n", to, from);185break;186case TGeneralString:187copy_primitive ("general_string", from, to);188break;189case TTeletexString:190copy_primitive ("general_string", from, to);191break;192case TUTCTime:193fprintf(codefile, "*(%s) = *(%s);\n", to, from);194break;195case TUTF8String:196copy_primitive ("utf8string", from, to);197break;198case TPrintableString:199copy_primitive ("printable_string", from, to);200break;201case TIA5String:202copy_primitive ("ia5_string", from, to);203break;204case TBMPString:205copy_primitive ("bmp_string", from, to);206break;207case TUniversalString:208copy_primitive ("universal_string", from, to);209break;210case TVisibleString:211copy_primitive ("visible_string", from, to);212break;213case TTag:214copy_type (from, to, t->subtype, preserve);215break;216case TOID:217copy_primitive ("oid", from, to);218break;219case TNull:220break;221default :222abort ();223}224}225226void227generate_type_copy (const Symbol *s)228{229int preserve = preserve_type(s->name) ? TRUE : FALSE;230231used_fail = 0;232233fprintf (codefile, "int ASN1CALL\n"234"copy_%s(const %s *from, %s *to)\n"235"{\n"236"memset(to, 0, sizeof(*to));\n",237s->gen_name, s->gen_name, s->gen_name);238copy_type ("from", "to", s->type, preserve);239fprintf (codefile, "return 0;\n");240241if (used_fail)242fprintf (codefile, "fail:\n"243"free_%s(to);\n"244"return ENOMEM;\n",245s->gen_name);246247fprintf(codefile,248"}\n\n");249}250251252253