1b528cefcSMark Murray /* 2ae771770SStanislav Sedov * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan 3b528cefcSMark Murray * (Royal Institute of Technology, Stockholm, Sweden). 4b528cefcSMark Murray * All rights reserved. 5b528cefcSMark Murray * 6b528cefcSMark Murray * Redistribution and use in source and binary forms, with or without 7b528cefcSMark Murray * modification, are permitted provided that the following conditions 8b528cefcSMark Murray * are met: 9b528cefcSMark Murray * 10b528cefcSMark Murray * 1. Redistributions of source code must retain the above copyright 11b528cefcSMark Murray * notice, this list of conditions and the following disclaimer. 12b528cefcSMark Murray * 13b528cefcSMark Murray * 2. Redistributions in binary form must reproduce the above copyright 14b528cefcSMark Murray * notice, this list of conditions and the following disclaimer in the 15b528cefcSMark Murray * documentation and/or other materials provided with the distribution. 16b528cefcSMark Murray * 17b528cefcSMark Murray * 3. Neither the name of the Institute nor the names of its contributors 18b528cefcSMark Murray * may be used to endorse or promote products derived from this software 19b528cefcSMark Murray * without specific prior written permission. 20b528cefcSMark Murray * 21b528cefcSMark Murray * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22b528cefcSMark Murray * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23b528cefcSMark Murray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24b528cefcSMark Murray * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25b528cefcSMark Murray * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26b528cefcSMark Murray * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27b528cefcSMark Murray * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28b528cefcSMark Murray * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29b528cefcSMark Murray * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30b528cefcSMark Murray * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31b528cefcSMark Murray * SUCH DAMAGE. 32b528cefcSMark Murray */ 33b528cefcSMark Murray 34b528cefcSMark Murray #include "gen_locl.h" 35b528cefcSMark Murray 36ae771770SStanislav Sedov RCSID("$Id$"); 37b528cefcSMark Murray 38b528cefcSMark Murray static void 39b528cefcSMark Murray encode_primitive (const char *typename, const char *name) 40b528cefcSMark Murray { 41b528cefcSMark Murray fprintf (codefile, 42c19800e8SDoug Rabson "e = der_put_%s(p, len, %s, &l);\n" 43c19800e8SDoug Rabson "if (e) return e;\np -= l; len -= l; ret += l;\n\n", 44b528cefcSMark Murray typename, 45b528cefcSMark Murray name); 46b528cefcSMark Murray } 47b528cefcSMark Murray 48c19800e8SDoug Rabson const char * 49c19800e8SDoug Rabson classname(Der_class class) 50b528cefcSMark Murray { 51c19800e8SDoug Rabson const char *cn[] = { "ASN1_C_UNIV", "ASN1_C_APPL", 52c19800e8SDoug Rabson "ASN1_C_CONTEXT", "ASN1_C_PRIV" }; 53c19800e8SDoug Rabson if(class < ASN1_C_UNIV || class > ASN1_C_PRIVATE) 54c19800e8SDoug Rabson return "???"; 55c19800e8SDoug Rabson return cn[class]; 56c19800e8SDoug Rabson } 57c19800e8SDoug Rabson 58c19800e8SDoug Rabson 59c19800e8SDoug Rabson const char * 60c19800e8SDoug Rabson valuename(Der_class class, int value) 61c19800e8SDoug Rabson { 62c19800e8SDoug Rabson static char s[32]; 63c19800e8SDoug Rabson struct { 64c19800e8SDoug Rabson int value; 65c19800e8SDoug Rabson const char *s; 66c19800e8SDoug Rabson } *p, values[] = { 67c19800e8SDoug Rabson #define X(Y) { Y, #Y } 68c19800e8SDoug Rabson X(UT_BMPString), 69c19800e8SDoug Rabson X(UT_BitString), 70c19800e8SDoug Rabson X(UT_Boolean), 71c19800e8SDoug Rabson X(UT_EmbeddedPDV), 72c19800e8SDoug Rabson X(UT_Enumerated), 73c19800e8SDoug Rabson X(UT_External), 74c19800e8SDoug Rabson X(UT_GeneralString), 75c19800e8SDoug Rabson X(UT_GeneralizedTime), 76c19800e8SDoug Rabson X(UT_GraphicString), 77c19800e8SDoug Rabson X(UT_IA5String), 78c19800e8SDoug Rabson X(UT_Integer), 79c19800e8SDoug Rabson X(UT_Null), 80c19800e8SDoug Rabson X(UT_NumericString), 81c19800e8SDoug Rabson X(UT_OID), 82c19800e8SDoug Rabson X(UT_ObjectDescriptor), 83c19800e8SDoug Rabson X(UT_OctetString), 84c19800e8SDoug Rabson X(UT_PrintableString), 85c19800e8SDoug Rabson X(UT_Real), 86c19800e8SDoug Rabson X(UT_RelativeOID), 87c19800e8SDoug Rabson X(UT_Sequence), 88c19800e8SDoug Rabson X(UT_Set), 89c19800e8SDoug Rabson X(UT_TeletexString), 90c19800e8SDoug Rabson X(UT_UTCTime), 91c19800e8SDoug Rabson X(UT_UTF8String), 92c19800e8SDoug Rabson X(UT_UniversalString), 93c19800e8SDoug Rabson X(UT_VideotexString), 94c19800e8SDoug Rabson X(UT_VisibleString), 95c19800e8SDoug Rabson #undef X 96c19800e8SDoug Rabson { -1, NULL } 97c19800e8SDoug Rabson }; 98c19800e8SDoug Rabson if(class == ASN1_C_UNIV) { 99c19800e8SDoug Rabson for(p = values; p->value != -1; p++) 100c19800e8SDoug Rabson if(p->value == value) 101c19800e8SDoug Rabson return p->s; 102c19800e8SDoug Rabson } 103c19800e8SDoug Rabson snprintf(s, sizeof(s), "%d", value); 104c19800e8SDoug Rabson return s; 105c19800e8SDoug Rabson } 106c19800e8SDoug Rabson 107c19800e8SDoug Rabson static int 108c19800e8SDoug Rabson encode_type (const char *name, const Type *t, const char *tmpstr) 109c19800e8SDoug Rabson { 110c19800e8SDoug Rabson int constructed = 1; 111c19800e8SDoug Rabson 112b528cefcSMark Murray switch (t->type) { 113b528cefcSMark Murray case TType: 114b528cefcSMark Murray #if 0 115b528cefcSMark Murray encode_type (name, t->symbol->type); 116b528cefcSMark Murray #endif 117b528cefcSMark Murray fprintf (codefile, 118b528cefcSMark Murray "e = encode_%s(p, len, %s, &l);\n" 119c19800e8SDoug Rabson "if (e) return e;\np -= l; len -= l; ret += l;\n\n", 120b528cefcSMark Murray t->symbol->gen_name, name); 121b528cefcSMark Murray break; 122b528cefcSMark Murray case TInteger: 123c19800e8SDoug Rabson if(t->members) { 124c19800e8SDoug Rabson fprintf(codefile, 125c19800e8SDoug Rabson "{\n" 126c19800e8SDoug Rabson "int enumint = (int)*%s;\n", 127c19800e8SDoug Rabson name); 128c19800e8SDoug Rabson encode_primitive ("integer", "&enumint"); 129c19800e8SDoug Rabson fprintf(codefile, "}\n;"); 130c19800e8SDoug Rabson } else if (t->range == NULL) { 131c19800e8SDoug Rabson encode_primitive ("heim_integer", name); 132*1b748759SDimitry Andric } else if (t->range->min < INT_MIN && t->range->max <= INT64_MAX) { 133*1b748759SDimitry Andric encode_primitive ("integer64", name); 134*1b748759SDimitry Andric } else if (t->range->min >= 0 && t->range->max > UINT_MAX) { 135*1b748759SDimitry Andric encode_primitive ("unsigned64", name); 136*1b748759SDimitry Andric } else if (t->range->min >= INT_MIN && t->range->max <= INT_MAX) { 137b528cefcSMark Murray encode_primitive ("integer", name); 138*1b748759SDimitry Andric } else if (t->range->min >= 0 && t->range->max <= UINT_MAX) { 139c19800e8SDoug Rabson encode_primitive ("unsigned", name); 140c19800e8SDoug Rabson } else 141*1b748759SDimitry Andric errx(1, "%s: unsupported range %" PRId64 " -> %" PRId64, 142c19800e8SDoug Rabson name, t->range->min, t->range->max); 143c19800e8SDoug Rabson constructed = 0; 144c19800e8SDoug Rabson break; 145c19800e8SDoug Rabson case TBoolean: 146c19800e8SDoug Rabson encode_primitive ("boolean", name); 147c19800e8SDoug Rabson constructed = 0; 148b528cefcSMark Murray break; 149b528cefcSMark Murray case TOctetString: 150b528cefcSMark Murray encode_primitive ("octet_string", name); 151c19800e8SDoug Rabson constructed = 0; 1524137ff4cSJacques Vidrine break; 153b528cefcSMark Murray case TBitString: { 154b528cefcSMark Murray Member *m; 155b528cefcSMark Murray int pos; 156b528cefcSMark Murray 157c19800e8SDoug Rabson if (ASN1_TAILQ_EMPTY(t->members)) { 158c19800e8SDoug Rabson encode_primitive("bit_string", name); 159c19800e8SDoug Rabson constructed = 0; 160b528cefcSMark Murray break; 161c19800e8SDoug Rabson } 162b528cefcSMark Murray 163b528cefcSMark Murray fprintf (codefile, "{\n" 164b528cefcSMark Murray "unsigned char c = 0;\n"); 165c19800e8SDoug Rabson if (!rfc1510_bitstring) 166c19800e8SDoug Rabson fprintf (codefile, 167c19800e8SDoug Rabson "int rest = 0;\n" 168c19800e8SDoug Rabson "int bit_set = 0;\n"); 169c19800e8SDoug Rabson #if 0 170b528cefcSMark Murray pos = t->members->prev->val; 171b528cefcSMark Murray /* fix for buggy MIT (and OSF?) code */ 172b528cefcSMark Murray if (pos > 31) 173b528cefcSMark Murray abort (); 174c19800e8SDoug Rabson #endif 175b528cefcSMark Murray /* 176b528cefcSMark Murray * It seems that if we do not always set pos to 31 here, the MIT 177b528cefcSMark Murray * code will do the wrong thing. 178b528cefcSMark Murray * 179b528cefcSMark Murray * I hate ASN.1 (and DER), but I hate it even more when everybody 180b528cefcSMark Murray * has to screw it up differently. 181b528cefcSMark Murray */ 182c19800e8SDoug Rabson pos = ASN1_TAILQ_LAST(t->members, memhead)->val; 183c19800e8SDoug Rabson if (rfc1510_bitstring) { 184c19800e8SDoug Rabson if (pos < 31) 185b528cefcSMark Murray pos = 31; 186c19800e8SDoug Rabson } 187b528cefcSMark Murray 188c19800e8SDoug Rabson ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) { 189b528cefcSMark Murray while (m->val / 8 < pos / 8) { 190c19800e8SDoug Rabson if (!rfc1510_bitstring) 191b528cefcSMark Murray fprintf (codefile, 192c19800e8SDoug Rabson "if (c != 0 || bit_set) {\n"); 193c19800e8SDoug Rabson fprintf (codefile, 194c19800e8SDoug Rabson "if (len < 1) return ASN1_OVERFLOW;\n" 195c19800e8SDoug Rabson "*p-- = c; len--; ret++;\n"); 196c19800e8SDoug Rabson if (!rfc1510_bitstring) 197c19800e8SDoug Rabson fprintf (codefile, 198c19800e8SDoug Rabson "if (!bit_set) {\n" 199c19800e8SDoug Rabson "rest = 0;\n" 200c19800e8SDoug Rabson "while(c) { \n" 201c19800e8SDoug Rabson "if (c & 1) break;\n" 202c19800e8SDoug Rabson "c = c >> 1;\n" 203c19800e8SDoug Rabson "rest++;\n" 204c19800e8SDoug Rabson "}\n" 205c19800e8SDoug Rabson "bit_set = 1;\n" 206c19800e8SDoug Rabson "}\n" 207c19800e8SDoug Rabson "}\n"); 208c19800e8SDoug Rabson fprintf (codefile, 209b528cefcSMark Murray "c = 0;\n"); 210b528cefcSMark Murray pos -= 8; 211b528cefcSMark Murray } 212b528cefcSMark Murray fprintf (codefile, 213c19800e8SDoug Rabson "if((%s)->%s) {\n" 214c19800e8SDoug Rabson "c |= 1<<%d;\n", 215c19800e8SDoug Rabson name, m->gen_name, 7 - m->val % 8); 216c19800e8SDoug Rabson fprintf (codefile, 217c19800e8SDoug Rabson "}\n"); 218b528cefcSMark Murray } 219b528cefcSMark Murray 220c19800e8SDoug Rabson if (!rfc1510_bitstring) 221b528cefcSMark Murray fprintf (codefile, 222c19800e8SDoug Rabson "if (c != 0 || bit_set) {\n"); 223c19800e8SDoug Rabson fprintf (codefile, 224c19800e8SDoug Rabson "if (len < 1) return ASN1_OVERFLOW;\n" 225c19800e8SDoug Rabson "*p-- = c; len--; ret++;\n"); 226c19800e8SDoug Rabson if (!rfc1510_bitstring) 227c19800e8SDoug Rabson fprintf (codefile, 228c19800e8SDoug Rabson "if (!bit_set) {\n" 229c19800e8SDoug Rabson "rest = 0;\n" 230c19800e8SDoug Rabson "if(c) { \n" 231c19800e8SDoug Rabson "while(c) { \n" 232c19800e8SDoug Rabson "if (c & 1) break;\n" 233c19800e8SDoug Rabson "c = c >> 1;\n" 234c19800e8SDoug Rabson "rest++;\n" 235c19800e8SDoug Rabson "}\n" 236c19800e8SDoug Rabson "}\n" 237c19800e8SDoug Rabson "}\n" 238c19800e8SDoug Rabson "}\n"); 239c19800e8SDoug Rabson 240c19800e8SDoug Rabson fprintf (codefile, 241c19800e8SDoug Rabson "if (len < 1) return ASN1_OVERFLOW;\n" 242c19800e8SDoug Rabson "*p-- = %s;\n" 243c19800e8SDoug Rabson "len -= 1;\n" 244c19800e8SDoug Rabson "ret += 1;\n" 245c19800e8SDoug Rabson "}\n\n", 246c19800e8SDoug Rabson rfc1510_bitstring ? "0" : "rest"); 247c19800e8SDoug Rabson constructed = 0; 248b528cefcSMark Murray break; 249b528cefcSMark Murray } 2504137ff4cSJacques Vidrine case TEnumerated : { 2514137ff4cSJacques Vidrine encode_primitive ("enumerated", name); 252c19800e8SDoug Rabson constructed = 0; 2534137ff4cSJacques Vidrine break; 2544137ff4cSJacques Vidrine } 255c19800e8SDoug Rabson 256c19800e8SDoug Rabson case TSet: 257b528cefcSMark Murray case TSequence: { 258b528cefcSMark Murray Member *m; 259b528cefcSMark Murray 260b528cefcSMark Murray if (t->members == NULL) 261b528cefcSMark Murray break; 262b528cefcSMark Murray 263c19800e8SDoug Rabson ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) { 264ae771770SStanislav Sedov char *s = NULL; 265b528cefcSMark Murray 266c19800e8SDoug Rabson if (m->ellipsis) 267c19800e8SDoug Rabson continue; 268c19800e8SDoug Rabson 269ae771770SStanislav Sedov if (asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name) < 0 || s == NULL) 270c19800e8SDoug Rabson errx(1, "malloc"); 271c19800e8SDoug Rabson fprintf(codefile, "/* %s */\n", m->name); 272b528cefcSMark Murray if (m->optional) 273b528cefcSMark Murray fprintf (codefile, 274c19800e8SDoug Rabson "if(%s) ", 275b528cefcSMark Murray s); 276c19800e8SDoug Rabson else if(m->defval) 277c19800e8SDoug Rabson gen_compare_defval(s + 1, m->defval); 278c19800e8SDoug Rabson fprintf (codefile, "{\n"); 279ae771770SStanislav Sedov fprintf (codefile, "size_t %s_oldret HEIMDAL_UNUSED_ATTRIBUTE = ret;\n", tmpstr); 280c19800e8SDoug Rabson fprintf (codefile, "ret = 0;\n"); 281c19800e8SDoug Rabson encode_type (s, m->type, m->gen_name); 282c19800e8SDoug Rabson fprintf (codefile, "ret += %s_oldret;\n", tmpstr); 283c19800e8SDoug Rabson fprintf (codefile, "}\n"); 284b528cefcSMark Murray free (s); 285b528cefcSMark Murray } 286c19800e8SDoug Rabson break; 287c19800e8SDoug Rabson } 288c19800e8SDoug Rabson case TSetOf: { 289c19800e8SDoug Rabson 290b528cefcSMark Murray fprintf(codefile, 291c19800e8SDoug Rabson "{\n" 292c19800e8SDoug Rabson "struct heim_octet_string *val;\n" 293ae771770SStanislav Sedov "size_t elen = 0, totallen = 0;\n" 294ae771770SStanislav Sedov "int eret = 0;\n"); 295c19800e8SDoug Rabson 296c19800e8SDoug Rabson fprintf(codefile, 297c19800e8SDoug Rabson "if ((%s)->len > UINT_MAX/sizeof(val[0]))\n" 298c19800e8SDoug Rabson "return ERANGE;\n", 299c19800e8SDoug Rabson name); 300c19800e8SDoug Rabson 301c19800e8SDoug Rabson fprintf(codefile, 302c19800e8SDoug Rabson "val = malloc(sizeof(val[0]) * (%s)->len);\n" 303c19800e8SDoug Rabson "if (val == NULL && (%s)->len != 0) return ENOMEM;\n", 304c19800e8SDoug Rabson name, name); 305c19800e8SDoug Rabson 306c19800e8SDoug Rabson fprintf(codefile, 307ae771770SStanislav Sedov "for(i = 0; i < (int)(%s)->len; i++) {\n", 308c19800e8SDoug Rabson name); 309c19800e8SDoug Rabson 310c19800e8SDoug Rabson fprintf(codefile, 311c19800e8SDoug Rabson "ASN1_MALLOC_ENCODE(%s, val[i].data, " 312c19800e8SDoug Rabson "val[i].length, &(%s)->val[i], &elen, eret);\n", 313c19800e8SDoug Rabson t->subtype->symbol->gen_name, 314c19800e8SDoug Rabson name); 315c19800e8SDoug Rabson 316c19800e8SDoug Rabson fprintf(codefile, 317c19800e8SDoug Rabson "if(eret) {\n" 318c19800e8SDoug Rabson "i--;\n" 319c19800e8SDoug Rabson "while (i >= 0) {\n" 320c19800e8SDoug Rabson "free(val[i].data);\n" 321c19800e8SDoug Rabson "i--;\n" 322c19800e8SDoug Rabson "}\n" 323c19800e8SDoug Rabson "free(val);\n" 324c19800e8SDoug Rabson "return eret;\n" 325c19800e8SDoug Rabson "}\n" 326c19800e8SDoug Rabson "totallen += elen;\n" 327c19800e8SDoug Rabson "}\n"); 328c19800e8SDoug Rabson 329c19800e8SDoug Rabson fprintf(codefile, 330c19800e8SDoug Rabson "if (totallen > len) {\n" 331ae771770SStanislav Sedov "for (i = 0; i < (int)(%s)->len; i++) {\n" 332c19800e8SDoug Rabson "free(val[i].data);\n" 333c19800e8SDoug Rabson "}\n" 334c19800e8SDoug Rabson "free(val);\n" 335c19800e8SDoug Rabson "return ASN1_OVERFLOW;\n" 336c19800e8SDoug Rabson "}\n", 337c19800e8SDoug Rabson name); 338c19800e8SDoug Rabson 339c19800e8SDoug Rabson fprintf(codefile, 340c19800e8SDoug Rabson "qsort(val, (%s)->len, sizeof(val[0]), _heim_der_set_sort);\n", 341c19800e8SDoug Rabson name); 342c19800e8SDoug Rabson 343c19800e8SDoug Rabson fprintf (codefile, 344ae771770SStanislav Sedov "for(i = (int)(%s)->len - 1; i >= 0; --i) {\n" 345c19800e8SDoug Rabson "p -= val[i].length;\n" 346c19800e8SDoug Rabson "ret += val[i].length;\n" 347c19800e8SDoug Rabson "memcpy(p + 1, val[i].data, val[i].length);\n" 348c19800e8SDoug Rabson "free(val[i].data);\n" 349c19800e8SDoug Rabson "}\n" 350c19800e8SDoug Rabson "free(val);\n" 351c19800e8SDoug Rabson "}\n", 352c19800e8SDoug Rabson name); 353b528cefcSMark Murray break; 354b528cefcSMark Murray } 355b528cefcSMark Murray case TSequenceOf: { 356ae771770SStanislav Sedov char *sname = NULL; 357ae771770SStanislav Sedov char *n = NULL; 358b528cefcSMark Murray 359b528cefcSMark Murray fprintf (codefile, 360ae771770SStanislav Sedov "for(i = (int)(%s)->len - 1; i >= 0; --i) {\n" 361c19800e8SDoug Rabson "size_t %s_for_oldret = ret;\n" 362b528cefcSMark Murray "ret = 0;\n", 363c19800e8SDoug Rabson name, tmpstr); 364ae771770SStanislav Sedov if (asprintf (&n, "&(%s)->val[i]", name) < 0 || n == NULL) 365c19800e8SDoug Rabson errx(1, "malloc"); 366ae771770SStanislav Sedov if (asprintf (&sname, "%s_S_Of", tmpstr) < 0 || sname == NULL) 367c19800e8SDoug Rabson errx(1, "malloc"); 368c19800e8SDoug Rabson encode_type (n, t->subtype, sname); 369b528cefcSMark Murray fprintf (codefile, 370c19800e8SDoug Rabson "ret += %s_for_oldret;\n" 371c19800e8SDoug Rabson "}\n", 372c19800e8SDoug Rabson tmpstr); 373b528cefcSMark Murray free (n); 374c19800e8SDoug Rabson free (sname); 375b528cefcSMark Murray break; 376b528cefcSMark Murray } 377b528cefcSMark Murray case TGeneralizedTime: 378b528cefcSMark Murray encode_primitive ("generalized_time", name); 379c19800e8SDoug Rabson constructed = 0; 380b528cefcSMark Murray break; 381b528cefcSMark Murray case TGeneralString: 382b528cefcSMark Murray encode_primitive ("general_string", name); 383c19800e8SDoug Rabson constructed = 0; 384b528cefcSMark Murray break; 385ae771770SStanislav Sedov case TTeletexString: 386ae771770SStanislav Sedov encode_primitive ("general_string", name); 387ae771770SStanislav Sedov constructed = 0; 388ae771770SStanislav Sedov break; 389c19800e8SDoug Rabson case TTag: { 390ae771770SStanislav Sedov char *tname = NULL; 391c19800e8SDoug Rabson int c; 392ae771770SStanislav Sedov if (asprintf (&tname, "%s_tag", tmpstr) < 0 || tname == NULL) 393c19800e8SDoug Rabson errx(1, "malloc"); 394c19800e8SDoug Rabson c = encode_type (name, t->subtype, tname); 395b528cefcSMark Murray fprintf (codefile, 396c19800e8SDoug Rabson "e = der_put_length_and_tag (p, len, ret, %s, %s, %s, &l);\n" 397c19800e8SDoug Rabson "if (e) return e;\np -= l; len -= l; ret += l;\n\n", 398c19800e8SDoug Rabson classname(t->tag.tagclass), 399c19800e8SDoug Rabson c ? "CONS" : "PRIM", 400c19800e8SDoug Rabson valuename(t->tag.tagclass, t->tag.tagvalue)); 401c19800e8SDoug Rabson free (tname); 402c19800e8SDoug Rabson break; 403c19800e8SDoug Rabson } 404c19800e8SDoug Rabson case TChoice:{ 405c19800e8SDoug Rabson Member *m, *have_ellipsis = NULL; 406ae771770SStanislav Sedov char *s = NULL; 407c19800e8SDoug Rabson 408c19800e8SDoug Rabson if (t->members == NULL) 409c19800e8SDoug Rabson break; 410c19800e8SDoug Rabson 411c19800e8SDoug Rabson fprintf(codefile, "\n"); 412c19800e8SDoug Rabson 413ae771770SStanislav Sedov if (asprintf (&s, "(%s)", name) < 0 || s == NULL) 414c19800e8SDoug Rabson errx(1, "malloc"); 415c19800e8SDoug Rabson fprintf(codefile, "switch(%s->element) {\n", s); 416c19800e8SDoug Rabson 417c19800e8SDoug Rabson ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) { 418ae771770SStanislav Sedov char *s2 = NULL; 419c19800e8SDoug Rabson 420c19800e8SDoug Rabson if (m->ellipsis) { 421c19800e8SDoug Rabson have_ellipsis = m; 422c19800e8SDoug Rabson continue; 423c19800e8SDoug Rabson } 424c19800e8SDoug Rabson 425c19800e8SDoug Rabson fprintf (codefile, "case %s: {", m->label); 426ae771770SStanislav Sedov if (asprintf(&s2, "%s(%s)->u.%s", m->optional ? "" : "&", 427ae771770SStanislav Sedov s, m->gen_name) < 0 || s2 == NULL) 428c19800e8SDoug Rabson errx(1, "malloc"); 429c19800e8SDoug Rabson if (m->optional) 430c19800e8SDoug Rabson fprintf (codefile, "if(%s) {\n", s2); 431c19800e8SDoug Rabson fprintf (codefile, "size_t %s_oldret = ret;\n", tmpstr); 432c19800e8SDoug Rabson fprintf (codefile, "ret = 0;\n"); 433c19800e8SDoug Rabson constructed = encode_type (s2, m->type, m->gen_name); 434c19800e8SDoug Rabson fprintf (codefile, "ret += %s_oldret;\n", tmpstr); 435c19800e8SDoug Rabson if(m->optional) 436c19800e8SDoug Rabson fprintf (codefile, "}\n"); 437c19800e8SDoug Rabson fprintf(codefile, "break;\n"); 438c19800e8SDoug Rabson fprintf(codefile, "}\n"); 439c19800e8SDoug Rabson free (s2); 440c19800e8SDoug Rabson } 441c19800e8SDoug Rabson free (s); 442c19800e8SDoug Rabson if (have_ellipsis) { 443c19800e8SDoug Rabson fprintf(codefile, 444c19800e8SDoug Rabson "case %s: {\n" 445c19800e8SDoug Rabson "if (len < (%s)->u.%s.length)\n" 446c19800e8SDoug Rabson "return ASN1_OVERFLOW;\n" 447c19800e8SDoug Rabson "p -= (%s)->u.%s.length;\n" 448c19800e8SDoug Rabson "ret += (%s)->u.%s.length;\n" 449c19800e8SDoug Rabson "memcpy(p + 1, (%s)->u.%s.data, (%s)->u.%s.length);\n" 450c19800e8SDoug Rabson "break;\n" 451c19800e8SDoug Rabson "}\n", 452c19800e8SDoug Rabson have_ellipsis->label, 453c19800e8SDoug Rabson name, have_ellipsis->gen_name, 454c19800e8SDoug Rabson name, have_ellipsis->gen_name, 455c19800e8SDoug Rabson name, have_ellipsis->gen_name, 456c19800e8SDoug Rabson name, have_ellipsis->gen_name, 457c19800e8SDoug Rabson name, have_ellipsis->gen_name); 458c19800e8SDoug Rabson } 459c19800e8SDoug Rabson fprintf(codefile, "};\n"); 460c19800e8SDoug Rabson break; 461c19800e8SDoug Rabson } 462c19800e8SDoug Rabson case TOID: 463c19800e8SDoug Rabson encode_primitive ("oid", name); 464c19800e8SDoug Rabson constructed = 0; 465c19800e8SDoug Rabson break; 466c19800e8SDoug Rabson case TUTCTime: 467c19800e8SDoug Rabson encode_primitive ("utctime", name); 468c19800e8SDoug Rabson constructed = 0; 469c19800e8SDoug Rabson break; 470c19800e8SDoug Rabson case TUTF8String: 471c19800e8SDoug Rabson encode_primitive ("utf8string", name); 472c19800e8SDoug Rabson constructed = 0; 473c19800e8SDoug Rabson break; 474c19800e8SDoug Rabson case TPrintableString: 475c19800e8SDoug Rabson encode_primitive ("printable_string", name); 476c19800e8SDoug Rabson constructed = 0; 477c19800e8SDoug Rabson break; 478c19800e8SDoug Rabson case TIA5String: 479c19800e8SDoug Rabson encode_primitive ("ia5_string", name); 480c19800e8SDoug Rabson constructed = 0; 481c19800e8SDoug Rabson break; 482c19800e8SDoug Rabson case TBMPString: 483c19800e8SDoug Rabson encode_primitive ("bmp_string", name); 484c19800e8SDoug Rabson constructed = 0; 485c19800e8SDoug Rabson break; 486c19800e8SDoug Rabson case TUniversalString: 487c19800e8SDoug Rabson encode_primitive ("universal_string", name); 488c19800e8SDoug Rabson constructed = 0; 489c19800e8SDoug Rabson break; 490c19800e8SDoug Rabson case TVisibleString: 491c19800e8SDoug Rabson encode_primitive ("visible_string", name); 492c19800e8SDoug Rabson constructed = 0; 493c19800e8SDoug Rabson break; 494c19800e8SDoug Rabson case TNull: 495c19800e8SDoug Rabson fprintf (codefile, "/* NULL */\n"); 496c19800e8SDoug Rabson constructed = 0; 497b528cefcSMark Murray break; 498b528cefcSMark Murray default: 499b528cefcSMark Murray abort (); 500b528cefcSMark Murray } 501c19800e8SDoug Rabson return constructed; 502b528cefcSMark Murray } 503b528cefcSMark Murray 504b528cefcSMark Murray void 505b528cefcSMark Murray generate_type_encode (const Symbol *s) 506b528cefcSMark Murray { 507ae771770SStanislav Sedov fprintf (codefile, "int ASN1CALL\n" 508ae771770SStanislav Sedov "encode_%s(unsigned char *p HEIMDAL_UNUSED_ATTRIBUTE, size_t len HEIMDAL_UNUSED_ATTRIBUTE," 509b528cefcSMark Murray " const %s *data, size_t *size)\n" 510b528cefcSMark Murray "{\n", 511b528cefcSMark Murray s->gen_name, s->gen_name); 512b528cefcSMark Murray 513b528cefcSMark Murray switch (s->type->type) { 514b528cefcSMark Murray case TInteger: 515c19800e8SDoug Rabson case TBoolean: 516b528cefcSMark Murray case TOctetString: 517b528cefcSMark Murray case TGeneralizedTime: 518b528cefcSMark Murray case TGeneralString: 519ae771770SStanislav Sedov case TTeletexString: 520c19800e8SDoug Rabson case TUTCTime: 521c19800e8SDoug Rabson case TUTF8String: 522c19800e8SDoug Rabson case TPrintableString: 523c19800e8SDoug Rabson case TIA5String: 524c19800e8SDoug Rabson case TBMPString: 525c19800e8SDoug Rabson case TUniversalString: 526c19800e8SDoug Rabson case TVisibleString: 527c19800e8SDoug Rabson case TNull: 528b528cefcSMark Murray case TBitString: 5294137ff4cSJacques Vidrine case TEnumerated: 5304137ff4cSJacques Vidrine case TOID: 531b528cefcSMark Murray case TSequence: 532b528cefcSMark Murray case TSequenceOf: 533c19800e8SDoug Rabson case TSet: 534c19800e8SDoug Rabson case TSetOf: 535c19800e8SDoug Rabson case TTag: 536b528cefcSMark Murray case TType: 537c19800e8SDoug Rabson case TChoice: 538b528cefcSMark Murray fprintf (codefile, 539ae771770SStanislav Sedov "size_t ret HEIMDAL_UNUSED_ATTRIBUTE = 0;\n" 540ae771770SStanislav Sedov "size_t l HEIMDAL_UNUSED_ATTRIBUTE;\n" 541ae771770SStanislav Sedov "int i HEIMDAL_UNUSED_ATTRIBUTE, e HEIMDAL_UNUSED_ATTRIBUTE;\n\n"); 542b528cefcSMark Murray 543c19800e8SDoug Rabson encode_type("data", s->type, "Top"); 5445e9cd1aeSAssar Westerlund 545b528cefcSMark Murray fprintf (codefile, "*size = ret;\n" 546b528cefcSMark Murray "return 0;\n"); 547b528cefcSMark Murray break; 548b528cefcSMark Murray default: 549b528cefcSMark Murray abort (); 550b528cefcSMark Murray } 551b528cefcSMark Murray fprintf (codefile, "}\n\n"); 552b528cefcSMark Murray } 553