1b528cefcSMark Murray /* 2*ae771770SStanislav 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 36*ae771770SStanislav 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); 132c19800e8SDoug Rabson } else if (t->range->min == INT_MIN && t->range->max == INT_MAX) { 133b528cefcSMark Murray encode_primitive ("integer", name); 134c19800e8SDoug Rabson } else if (t->range->min == 0 && t->range->max == UINT_MAX) { 1355e9cd1aeSAssar Westerlund encode_primitive ("unsigned", name); 136c19800e8SDoug Rabson } else if (t->range->min == 0 && t->range->max == INT_MAX) { 137c19800e8SDoug Rabson encode_primitive ("unsigned", name); 138c19800e8SDoug Rabson } else 139c19800e8SDoug Rabson errx(1, "%s: unsupported range %d -> %d", 140c19800e8SDoug Rabson name, t->range->min, t->range->max); 141c19800e8SDoug Rabson constructed = 0; 142c19800e8SDoug Rabson break; 143c19800e8SDoug Rabson case TBoolean: 144c19800e8SDoug Rabson encode_primitive ("boolean", name); 145c19800e8SDoug Rabson constructed = 0; 146b528cefcSMark Murray break; 147b528cefcSMark Murray case TOctetString: 148b528cefcSMark Murray encode_primitive ("octet_string", name); 149c19800e8SDoug Rabson constructed = 0; 1504137ff4cSJacques Vidrine break; 151b528cefcSMark Murray case TBitString: { 152b528cefcSMark Murray Member *m; 153b528cefcSMark Murray int pos; 154b528cefcSMark Murray 155c19800e8SDoug Rabson if (ASN1_TAILQ_EMPTY(t->members)) { 156c19800e8SDoug Rabson encode_primitive("bit_string", name); 157c19800e8SDoug Rabson constructed = 0; 158b528cefcSMark Murray break; 159c19800e8SDoug Rabson } 160b528cefcSMark Murray 161b528cefcSMark Murray fprintf (codefile, "{\n" 162b528cefcSMark Murray "unsigned char c = 0;\n"); 163c19800e8SDoug Rabson if (!rfc1510_bitstring) 164c19800e8SDoug Rabson fprintf (codefile, 165c19800e8SDoug Rabson "int rest = 0;\n" 166c19800e8SDoug Rabson "int bit_set = 0;\n"); 167c19800e8SDoug Rabson #if 0 168b528cefcSMark Murray pos = t->members->prev->val; 169b528cefcSMark Murray /* fix for buggy MIT (and OSF?) code */ 170b528cefcSMark Murray if (pos > 31) 171b528cefcSMark Murray abort (); 172c19800e8SDoug Rabson #endif 173b528cefcSMark Murray /* 174b528cefcSMark Murray * It seems that if we do not always set pos to 31 here, the MIT 175b528cefcSMark Murray * code will do the wrong thing. 176b528cefcSMark Murray * 177b528cefcSMark Murray * I hate ASN.1 (and DER), but I hate it even more when everybody 178b528cefcSMark Murray * has to screw it up differently. 179b528cefcSMark Murray */ 180c19800e8SDoug Rabson pos = ASN1_TAILQ_LAST(t->members, memhead)->val; 181c19800e8SDoug Rabson if (rfc1510_bitstring) { 182c19800e8SDoug Rabson if (pos < 31) 183b528cefcSMark Murray pos = 31; 184c19800e8SDoug Rabson } 185b528cefcSMark Murray 186c19800e8SDoug Rabson ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) { 187b528cefcSMark Murray while (m->val / 8 < pos / 8) { 188c19800e8SDoug Rabson if (!rfc1510_bitstring) 189b528cefcSMark Murray fprintf (codefile, 190c19800e8SDoug Rabson "if (c != 0 || bit_set) {\n"); 191c19800e8SDoug Rabson fprintf (codefile, 192c19800e8SDoug Rabson "if (len < 1) return ASN1_OVERFLOW;\n" 193c19800e8SDoug Rabson "*p-- = c; len--; ret++;\n"); 194c19800e8SDoug Rabson if (!rfc1510_bitstring) 195c19800e8SDoug Rabson fprintf (codefile, 196c19800e8SDoug Rabson "if (!bit_set) {\n" 197c19800e8SDoug Rabson "rest = 0;\n" 198c19800e8SDoug Rabson "while(c) { \n" 199c19800e8SDoug Rabson "if (c & 1) break;\n" 200c19800e8SDoug Rabson "c = c >> 1;\n" 201c19800e8SDoug Rabson "rest++;\n" 202c19800e8SDoug Rabson "}\n" 203c19800e8SDoug Rabson "bit_set = 1;\n" 204c19800e8SDoug Rabson "}\n" 205c19800e8SDoug Rabson "}\n"); 206c19800e8SDoug Rabson fprintf (codefile, 207b528cefcSMark Murray "c = 0;\n"); 208b528cefcSMark Murray pos -= 8; 209b528cefcSMark Murray } 210b528cefcSMark Murray fprintf (codefile, 211c19800e8SDoug Rabson "if((%s)->%s) {\n" 212c19800e8SDoug Rabson "c |= 1<<%d;\n", 213c19800e8SDoug Rabson name, m->gen_name, 7 - m->val % 8); 214c19800e8SDoug Rabson fprintf (codefile, 215c19800e8SDoug Rabson "}\n"); 216b528cefcSMark Murray } 217b528cefcSMark Murray 218c19800e8SDoug Rabson if (!rfc1510_bitstring) 219b528cefcSMark Murray fprintf (codefile, 220c19800e8SDoug Rabson "if (c != 0 || bit_set) {\n"); 221c19800e8SDoug Rabson fprintf (codefile, 222c19800e8SDoug Rabson "if (len < 1) return ASN1_OVERFLOW;\n" 223c19800e8SDoug Rabson "*p-- = c; len--; ret++;\n"); 224c19800e8SDoug Rabson if (!rfc1510_bitstring) 225c19800e8SDoug Rabson fprintf (codefile, 226c19800e8SDoug Rabson "if (!bit_set) {\n" 227c19800e8SDoug Rabson "rest = 0;\n" 228c19800e8SDoug Rabson "if(c) { \n" 229c19800e8SDoug Rabson "while(c) { \n" 230c19800e8SDoug Rabson "if (c & 1) break;\n" 231c19800e8SDoug Rabson "c = c >> 1;\n" 232c19800e8SDoug Rabson "rest++;\n" 233c19800e8SDoug Rabson "}\n" 234c19800e8SDoug Rabson "}\n" 235c19800e8SDoug Rabson "}\n" 236c19800e8SDoug Rabson "}\n"); 237c19800e8SDoug Rabson 238c19800e8SDoug Rabson fprintf (codefile, 239c19800e8SDoug Rabson "if (len < 1) return ASN1_OVERFLOW;\n" 240c19800e8SDoug Rabson "*p-- = %s;\n" 241c19800e8SDoug Rabson "len -= 1;\n" 242c19800e8SDoug Rabson "ret += 1;\n" 243c19800e8SDoug Rabson "}\n\n", 244c19800e8SDoug Rabson rfc1510_bitstring ? "0" : "rest"); 245c19800e8SDoug Rabson constructed = 0; 246b528cefcSMark Murray break; 247b528cefcSMark Murray } 2484137ff4cSJacques Vidrine case TEnumerated : { 2494137ff4cSJacques Vidrine encode_primitive ("enumerated", name); 250c19800e8SDoug Rabson constructed = 0; 2514137ff4cSJacques Vidrine break; 2524137ff4cSJacques Vidrine } 253c19800e8SDoug Rabson 254c19800e8SDoug Rabson case TSet: 255b528cefcSMark Murray case TSequence: { 256b528cefcSMark Murray Member *m; 257b528cefcSMark Murray 258b528cefcSMark Murray if (t->members == NULL) 259b528cefcSMark Murray break; 260b528cefcSMark Murray 261c19800e8SDoug Rabson ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) { 262*ae771770SStanislav Sedov char *s = NULL; 263b528cefcSMark Murray 264c19800e8SDoug Rabson if (m->ellipsis) 265c19800e8SDoug Rabson continue; 266c19800e8SDoug Rabson 267*ae771770SStanislav Sedov if (asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name) < 0 || s == NULL) 268c19800e8SDoug Rabson errx(1, "malloc"); 269c19800e8SDoug Rabson fprintf(codefile, "/* %s */\n", m->name); 270b528cefcSMark Murray if (m->optional) 271b528cefcSMark Murray fprintf (codefile, 272c19800e8SDoug Rabson "if(%s) ", 273b528cefcSMark Murray s); 274c19800e8SDoug Rabson else if(m->defval) 275c19800e8SDoug Rabson gen_compare_defval(s + 1, m->defval); 276c19800e8SDoug Rabson fprintf (codefile, "{\n"); 277*ae771770SStanislav Sedov fprintf (codefile, "size_t %s_oldret HEIMDAL_UNUSED_ATTRIBUTE = ret;\n", tmpstr); 278c19800e8SDoug Rabson fprintf (codefile, "ret = 0;\n"); 279c19800e8SDoug Rabson encode_type (s, m->type, m->gen_name); 280c19800e8SDoug Rabson fprintf (codefile, "ret += %s_oldret;\n", tmpstr); 281c19800e8SDoug Rabson fprintf (codefile, "}\n"); 282b528cefcSMark Murray free (s); 283b528cefcSMark Murray } 284c19800e8SDoug Rabson break; 285c19800e8SDoug Rabson } 286c19800e8SDoug Rabson case TSetOf: { 287c19800e8SDoug Rabson 288b528cefcSMark Murray fprintf(codefile, 289c19800e8SDoug Rabson "{\n" 290c19800e8SDoug Rabson "struct heim_octet_string *val;\n" 291*ae771770SStanislav Sedov "size_t elen = 0, totallen = 0;\n" 292*ae771770SStanislav Sedov "int eret = 0;\n"); 293c19800e8SDoug Rabson 294c19800e8SDoug Rabson fprintf(codefile, 295c19800e8SDoug Rabson "if ((%s)->len > UINT_MAX/sizeof(val[0]))\n" 296c19800e8SDoug Rabson "return ERANGE;\n", 297c19800e8SDoug Rabson name); 298c19800e8SDoug Rabson 299c19800e8SDoug Rabson fprintf(codefile, 300c19800e8SDoug Rabson "val = malloc(sizeof(val[0]) * (%s)->len);\n" 301c19800e8SDoug Rabson "if (val == NULL && (%s)->len != 0) return ENOMEM;\n", 302c19800e8SDoug Rabson name, name); 303c19800e8SDoug Rabson 304c19800e8SDoug Rabson fprintf(codefile, 305*ae771770SStanislav Sedov "for(i = 0; i < (int)(%s)->len; i++) {\n", 306c19800e8SDoug Rabson name); 307c19800e8SDoug Rabson 308c19800e8SDoug Rabson fprintf(codefile, 309c19800e8SDoug Rabson "ASN1_MALLOC_ENCODE(%s, val[i].data, " 310c19800e8SDoug Rabson "val[i].length, &(%s)->val[i], &elen, eret);\n", 311c19800e8SDoug Rabson t->subtype->symbol->gen_name, 312c19800e8SDoug Rabson name); 313c19800e8SDoug Rabson 314c19800e8SDoug Rabson fprintf(codefile, 315c19800e8SDoug Rabson "if(eret) {\n" 316c19800e8SDoug Rabson "i--;\n" 317c19800e8SDoug Rabson "while (i >= 0) {\n" 318c19800e8SDoug Rabson "free(val[i].data);\n" 319c19800e8SDoug Rabson "i--;\n" 320c19800e8SDoug Rabson "}\n" 321c19800e8SDoug Rabson "free(val);\n" 322c19800e8SDoug Rabson "return eret;\n" 323c19800e8SDoug Rabson "}\n" 324c19800e8SDoug Rabson "totallen += elen;\n" 325c19800e8SDoug Rabson "}\n"); 326c19800e8SDoug Rabson 327c19800e8SDoug Rabson fprintf(codefile, 328c19800e8SDoug Rabson "if (totallen > len) {\n" 329*ae771770SStanislav Sedov "for (i = 0; i < (int)(%s)->len; i++) {\n" 330c19800e8SDoug Rabson "free(val[i].data);\n" 331c19800e8SDoug Rabson "}\n" 332c19800e8SDoug Rabson "free(val);\n" 333c19800e8SDoug Rabson "return ASN1_OVERFLOW;\n" 334c19800e8SDoug Rabson "}\n", 335c19800e8SDoug Rabson name); 336c19800e8SDoug Rabson 337c19800e8SDoug Rabson fprintf(codefile, 338c19800e8SDoug Rabson "qsort(val, (%s)->len, sizeof(val[0]), _heim_der_set_sort);\n", 339c19800e8SDoug Rabson name); 340c19800e8SDoug Rabson 341c19800e8SDoug Rabson fprintf (codefile, 342*ae771770SStanislav Sedov "for(i = (int)(%s)->len - 1; i >= 0; --i) {\n" 343c19800e8SDoug Rabson "p -= val[i].length;\n" 344c19800e8SDoug Rabson "ret += val[i].length;\n" 345c19800e8SDoug Rabson "memcpy(p + 1, val[i].data, val[i].length);\n" 346c19800e8SDoug Rabson "free(val[i].data);\n" 347c19800e8SDoug Rabson "}\n" 348c19800e8SDoug Rabson "free(val);\n" 349c19800e8SDoug Rabson "}\n", 350c19800e8SDoug Rabson name); 351b528cefcSMark Murray break; 352b528cefcSMark Murray } 353b528cefcSMark Murray case TSequenceOf: { 354*ae771770SStanislav Sedov char *sname = NULL; 355*ae771770SStanislav Sedov char *n = NULL; 356b528cefcSMark Murray 357b528cefcSMark Murray fprintf (codefile, 358*ae771770SStanislav Sedov "for(i = (int)(%s)->len - 1; i >= 0; --i) {\n" 359c19800e8SDoug Rabson "size_t %s_for_oldret = ret;\n" 360b528cefcSMark Murray "ret = 0;\n", 361c19800e8SDoug Rabson name, tmpstr); 362*ae771770SStanislav Sedov if (asprintf (&n, "&(%s)->val[i]", name) < 0 || n == NULL) 363c19800e8SDoug Rabson errx(1, "malloc"); 364*ae771770SStanislav Sedov if (asprintf (&sname, "%s_S_Of", tmpstr) < 0 || sname == NULL) 365c19800e8SDoug Rabson errx(1, "malloc"); 366c19800e8SDoug Rabson encode_type (n, t->subtype, sname); 367b528cefcSMark Murray fprintf (codefile, 368c19800e8SDoug Rabson "ret += %s_for_oldret;\n" 369c19800e8SDoug Rabson "}\n", 370c19800e8SDoug Rabson tmpstr); 371b528cefcSMark Murray free (n); 372c19800e8SDoug Rabson free (sname); 373b528cefcSMark Murray break; 374b528cefcSMark Murray } 375b528cefcSMark Murray case TGeneralizedTime: 376b528cefcSMark Murray encode_primitive ("generalized_time", name); 377c19800e8SDoug Rabson constructed = 0; 378b528cefcSMark Murray break; 379b528cefcSMark Murray case TGeneralString: 380b528cefcSMark Murray encode_primitive ("general_string", name); 381c19800e8SDoug Rabson constructed = 0; 382b528cefcSMark Murray break; 383*ae771770SStanislav Sedov case TTeletexString: 384*ae771770SStanislav Sedov encode_primitive ("general_string", name); 385*ae771770SStanislav Sedov constructed = 0; 386*ae771770SStanislav Sedov break; 387c19800e8SDoug Rabson case TTag: { 388*ae771770SStanislav Sedov char *tname = NULL; 389c19800e8SDoug Rabson int c; 390*ae771770SStanislav Sedov if (asprintf (&tname, "%s_tag", tmpstr) < 0 || tname == NULL) 391c19800e8SDoug Rabson errx(1, "malloc"); 392c19800e8SDoug Rabson c = encode_type (name, t->subtype, tname); 393b528cefcSMark Murray fprintf (codefile, 394c19800e8SDoug Rabson "e = der_put_length_and_tag (p, len, ret, %s, %s, %s, &l);\n" 395c19800e8SDoug Rabson "if (e) return e;\np -= l; len -= l; ret += l;\n\n", 396c19800e8SDoug Rabson classname(t->tag.tagclass), 397c19800e8SDoug Rabson c ? "CONS" : "PRIM", 398c19800e8SDoug Rabson valuename(t->tag.tagclass, t->tag.tagvalue)); 399c19800e8SDoug Rabson free (tname); 400c19800e8SDoug Rabson break; 401c19800e8SDoug Rabson } 402c19800e8SDoug Rabson case TChoice:{ 403c19800e8SDoug Rabson Member *m, *have_ellipsis = NULL; 404*ae771770SStanislav Sedov char *s = NULL; 405c19800e8SDoug Rabson 406c19800e8SDoug Rabson if (t->members == NULL) 407c19800e8SDoug Rabson break; 408c19800e8SDoug Rabson 409c19800e8SDoug Rabson fprintf(codefile, "\n"); 410c19800e8SDoug Rabson 411*ae771770SStanislav Sedov if (asprintf (&s, "(%s)", name) < 0 || s == NULL) 412c19800e8SDoug Rabson errx(1, "malloc"); 413c19800e8SDoug Rabson fprintf(codefile, "switch(%s->element) {\n", s); 414c19800e8SDoug Rabson 415c19800e8SDoug Rabson ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) { 416*ae771770SStanislav Sedov char *s2 = NULL; 417c19800e8SDoug Rabson 418c19800e8SDoug Rabson if (m->ellipsis) { 419c19800e8SDoug Rabson have_ellipsis = m; 420c19800e8SDoug Rabson continue; 421c19800e8SDoug Rabson } 422c19800e8SDoug Rabson 423c19800e8SDoug Rabson fprintf (codefile, "case %s: {", m->label); 424*ae771770SStanislav Sedov if (asprintf(&s2, "%s(%s)->u.%s", m->optional ? "" : "&", 425*ae771770SStanislav Sedov s, m->gen_name) < 0 || s2 == NULL) 426c19800e8SDoug Rabson errx(1, "malloc"); 427c19800e8SDoug Rabson if (m->optional) 428c19800e8SDoug Rabson fprintf (codefile, "if(%s) {\n", s2); 429c19800e8SDoug Rabson fprintf (codefile, "size_t %s_oldret = ret;\n", tmpstr); 430c19800e8SDoug Rabson fprintf (codefile, "ret = 0;\n"); 431c19800e8SDoug Rabson constructed = encode_type (s2, m->type, m->gen_name); 432c19800e8SDoug Rabson fprintf (codefile, "ret += %s_oldret;\n", tmpstr); 433c19800e8SDoug Rabson if(m->optional) 434c19800e8SDoug Rabson fprintf (codefile, "}\n"); 435c19800e8SDoug Rabson fprintf(codefile, "break;\n"); 436c19800e8SDoug Rabson fprintf(codefile, "}\n"); 437c19800e8SDoug Rabson free (s2); 438c19800e8SDoug Rabson } 439c19800e8SDoug Rabson free (s); 440c19800e8SDoug Rabson if (have_ellipsis) { 441c19800e8SDoug Rabson fprintf(codefile, 442c19800e8SDoug Rabson "case %s: {\n" 443c19800e8SDoug Rabson "if (len < (%s)->u.%s.length)\n" 444c19800e8SDoug Rabson "return ASN1_OVERFLOW;\n" 445c19800e8SDoug Rabson "p -= (%s)->u.%s.length;\n" 446c19800e8SDoug Rabson "ret += (%s)->u.%s.length;\n" 447c19800e8SDoug Rabson "memcpy(p + 1, (%s)->u.%s.data, (%s)->u.%s.length);\n" 448c19800e8SDoug Rabson "break;\n" 449c19800e8SDoug Rabson "}\n", 450c19800e8SDoug Rabson have_ellipsis->label, 451c19800e8SDoug Rabson name, have_ellipsis->gen_name, 452c19800e8SDoug Rabson name, have_ellipsis->gen_name, 453c19800e8SDoug Rabson name, have_ellipsis->gen_name, 454c19800e8SDoug Rabson name, have_ellipsis->gen_name, 455c19800e8SDoug Rabson name, have_ellipsis->gen_name); 456c19800e8SDoug Rabson } 457c19800e8SDoug Rabson fprintf(codefile, "};\n"); 458c19800e8SDoug Rabson break; 459c19800e8SDoug Rabson } 460c19800e8SDoug Rabson case TOID: 461c19800e8SDoug Rabson encode_primitive ("oid", name); 462c19800e8SDoug Rabson constructed = 0; 463c19800e8SDoug Rabson break; 464c19800e8SDoug Rabson case TUTCTime: 465c19800e8SDoug Rabson encode_primitive ("utctime", name); 466c19800e8SDoug Rabson constructed = 0; 467c19800e8SDoug Rabson break; 468c19800e8SDoug Rabson case TUTF8String: 469c19800e8SDoug Rabson encode_primitive ("utf8string", name); 470c19800e8SDoug Rabson constructed = 0; 471c19800e8SDoug Rabson break; 472c19800e8SDoug Rabson case TPrintableString: 473c19800e8SDoug Rabson encode_primitive ("printable_string", name); 474c19800e8SDoug Rabson constructed = 0; 475c19800e8SDoug Rabson break; 476c19800e8SDoug Rabson case TIA5String: 477c19800e8SDoug Rabson encode_primitive ("ia5_string", name); 478c19800e8SDoug Rabson constructed = 0; 479c19800e8SDoug Rabson break; 480c19800e8SDoug Rabson case TBMPString: 481c19800e8SDoug Rabson encode_primitive ("bmp_string", name); 482c19800e8SDoug Rabson constructed = 0; 483c19800e8SDoug Rabson break; 484c19800e8SDoug Rabson case TUniversalString: 485c19800e8SDoug Rabson encode_primitive ("universal_string", name); 486c19800e8SDoug Rabson constructed = 0; 487c19800e8SDoug Rabson break; 488c19800e8SDoug Rabson case TVisibleString: 489c19800e8SDoug Rabson encode_primitive ("visible_string", name); 490c19800e8SDoug Rabson constructed = 0; 491c19800e8SDoug Rabson break; 492c19800e8SDoug Rabson case TNull: 493c19800e8SDoug Rabson fprintf (codefile, "/* NULL */\n"); 494c19800e8SDoug Rabson constructed = 0; 495b528cefcSMark Murray break; 496b528cefcSMark Murray default: 497b528cefcSMark Murray abort (); 498b528cefcSMark Murray } 499c19800e8SDoug Rabson return constructed; 500b528cefcSMark Murray } 501b528cefcSMark Murray 502b528cefcSMark Murray void 503b528cefcSMark Murray generate_type_encode (const Symbol *s) 504b528cefcSMark Murray { 505*ae771770SStanislav Sedov fprintf (codefile, "int ASN1CALL\n" 506*ae771770SStanislav Sedov "encode_%s(unsigned char *p HEIMDAL_UNUSED_ATTRIBUTE, size_t len HEIMDAL_UNUSED_ATTRIBUTE," 507b528cefcSMark Murray " const %s *data, size_t *size)\n" 508b528cefcSMark Murray "{\n", 509b528cefcSMark Murray s->gen_name, s->gen_name); 510b528cefcSMark Murray 511b528cefcSMark Murray switch (s->type->type) { 512b528cefcSMark Murray case TInteger: 513c19800e8SDoug Rabson case TBoolean: 514b528cefcSMark Murray case TOctetString: 515b528cefcSMark Murray case TGeneralizedTime: 516b528cefcSMark Murray case TGeneralString: 517*ae771770SStanislav Sedov case TTeletexString: 518c19800e8SDoug Rabson case TUTCTime: 519c19800e8SDoug Rabson case TUTF8String: 520c19800e8SDoug Rabson case TPrintableString: 521c19800e8SDoug Rabson case TIA5String: 522c19800e8SDoug Rabson case TBMPString: 523c19800e8SDoug Rabson case TUniversalString: 524c19800e8SDoug Rabson case TVisibleString: 525c19800e8SDoug Rabson case TNull: 526b528cefcSMark Murray case TBitString: 5274137ff4cSJacques Vidrine case TEnumerated: 5284137ff4cSJacques Vidrine case TOID: 529b528cefcSMark Murray case TSequence: 530b528cefcSMark Murray case TSequenceOf: 531c19800e8SDoug Rabson case TSet: 532c19800e8SDoug Rabson case TSetOf: 533c19800e8SDoug Rabson case TTag: 534b528cefcSMark Murray case TType: 535c19800e8SDoug Rabson case TChoice: 536b528cefcSMark Murray fprintf (codefile, 537*ae771770SStanislav Sedov "size_t ret HEIMDAL_UNUSED_ATTRIBUTE = 0;\n" 538*ae771770SStanislav Sedov "size_t l HEIMDAL_UNUSED_ATTRIBUTE;\n" 539*ae771770SStanislav Sedov "int i HEIMDAL_UNUSED_ATTRIBUTE, e HEIMDAL_UNUSED_ATTRIBUTE;\n\n"); 540b528cefcSMark Murray 541c19800e8SDoug Rabson encode_type("data", s->type, "Top"); 5425e9cd1aeSAssar Westerlund 543b528cefcSMark Murray fprintf (codefile, "*size = ret;\n" 544b528cefcSMark Murray "return 0;\n"); 545b528cefcSMark Murray break; 546b528cefcSMark Murray default: 547b528cefcSMark Murray abort (); 548b528cefcSMark Murray } 549b528cefcSMark Murray fprintf (codefile, "}\n\n"); 550b528cefcSMark Murray } 551