Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1744 lines
54 KiB

  1. /* Copyright (C) Boris Nikolaus, Germany, 1996-1997. All rights reserved. */
  2. /* Copyright (C) Microsoft Corporation, 1997-1998. All rights reserved. */
  3. #include "precomp.h"
  4. #include "optcase.h"
  5. // encode
  6. #define LEN_OFFSET_STR2 "nExplTagLenOff"
  7. #define LEN_OFFSET_STR "nLenOff"
  8. // decode
  9. #define DECODER_NAME "dd"
  10. #define STREAM_END_NAME "di"
  11. #define DECODER_NAME2 "pExplTagDec"
  12. #define STREAM_END_NAME2 "pbExplTagDataEnd"
  13. void GenBERFuncSimpleType(AssignmentList_t ass, BERTypeInfo_t *info, char *valref, TypeFunc_e et, char *encref, char *tagref);
  14. void GenBERStringTableSimpleType(AssignmentList_t ass, BERTypeInfo_t *info, char *valref);
  15. void GenBEREncSimpleType(AssignmentList_t ass, BERTypeInfo_t *info, char *valref, char *encref, char *tagref);
  16. void GenBEREncGenericUnextended(
  17. AssignmentList_t ass,
  18. BERTypeInfo_t *info,
  19. char *valref,
  20. char *lenref,
  21. char *encref,
  22. char *tagref);
  23. void GenBERFuncComponents(AssignmentList_t ass, char *module, uint32_t optindex, ComponentList_t components, char *valref, char *encref, char *oref, TypeFunc_e et, BERTypeInfo_t *, int *);
  24. void GenBERFuncSequenceSetType(AssignmentList_t ass, char *module, Assignment_t *at, char *valref, char *encref, TypeFunc_e et, char *tagref);
  25. void GenBERFuncChoiceType(AssignmentList_t ass, char *module, Assignment_t *at, char *valref, char *encref, TypeFunc_e et, char *tagref);
  26. void GenBERDecSimpleType(AssignmentList_t ass, BERTypeInfo_t *info, char *valref, char *encref, char *tagref);
  27. void GenBERDecGenericUnextended(
  28. AssignmentList_t ass,
  29. BERTypeInfo_t *info,
  30. char *valref,
  31. char *lenref,
  32. char *encref,
  33. char *tagref);
  34. extern int g_fDecZeroMemory;
  35. extern int g_nDbgModuleName;
  36. extern int g_fCaseBasedOptimizer;
  37. extern int g_fNoAssert;
  38. extern unsigned g_cPDUs;
  39. int IsComponentOpenType(Component_t *com)
  40. {
  41. if (eType_Open == com->U.NOD.NamedType->Type->Type)
  42. {
  43. return 1;
  44. }
  45. if (eType_Reference == com->U.NOD.NamedType->Type->Type)
  46. {
  47. if (eBERSTIData_Open == com->U.NOD.NamedType->Type->BERTypeInfo.Data)
  48. {
  49. return 1;
  50. }
  51. }
  52. return 0;
  53. }
  54. Component_t * FindOpenTypeComponent(ComponentList_t components)
  55. {
  56. Component_t *com = NULL;
  57. for (com = components; com; com = com->Next)
  58. {
  59. if (IsComponentOpenType(com))
  60. {
  61. break;
  62. }
  63. }
  64. return com;
  65. }
  66. /* write header needed for BER encodings */
  67. void
  68. GenBERHeader()
  69. {
  70. // output("#include \"berfnlib.h\"\n");
  71. }
  72. /* set prototypes and function args of BER functions */
  73. void
  74. GetBERPrototype(Arguments_t *args)
  75. {
  76. args->enccast = "ASN1encoding_t, ASN1uint32_t, void *";
  77. args->encfunc = "ASN1encoding_t enc, ASN1uint32_t tag, %s *val";
  78. args->Pencfunc = "ASN1encoding_t enc, ASN1uint32_t tag, P%s *val";
  79. args->deccast = "ASN1decoding_t, ASN1uint32_t, void *";
  80. args->decfunc = "ASN1decoding_t dec, ASN1uint32_t tag, %s *val";
  81. args->Pdecfunc = "ASN1decoding_t dec, ASN1uint32_t tag, P%s *val";
  82. args->freecast = "void *";
  83. args->freefunc = "%s *val";
  84. args->Pfreefunc = "P%s *val";
  85. args->cmpcast = "void *, void *";
  86. args->cmpfunc = "%s *val1, %s *val2";
  87. args->Pcmpfunc = "P%s *val1, P%s *val2";
  88. }
  89. /* write initialization function needed for BER encodings */
  90. void
  91. GenBERInit(AssignmentList_t ass, char *module)
  92. {
  93. char *pszRule;
  94. switch (g_eSubEncodingRule)
  95. {
  96. default:
  97. case eSubEncoding_Basic:
  98. pszRule = "ASN1_BER_RULE_BER";
  99. break;
  100. case eSubEncoding_Canonical:
  101. pszRule = "ASN1_BER_RULE_CER";
  102. break;
  103. case eSubEncoding_Distinguished:
  104. pszRule = "ASN1_BER_RULE_DER";
  105. break;
  106. }
  107. output("%s = ASN1_CreateModule(0x%x, %s, %s, %d, (const ASN1GenericFun_t *) encfntab, (const ASN1GenericFun_t *) decfntab, freefntab, sizetab, 0x%lx);\n",
  108. module,
  109. ASN1_THIS_VERSION,
  110. pszRule,
  111. g_fNoAssert ? "ASN1FLAGS_NOASSERT" : "ASN1FLAGS_NONE",
  112. g_cPDUs,
  113. g_nDbgModuleName);
  114. }
  115. /* convert a tag to an uint32_t: */
  116. /* bits 0..29: tag value */
  117. /* bits 30..31: tag class */
  118. uint32_t
  119. Tag2uint32(AssignmentList_t ass, Tag_t *tag)
  120. {
  121. uint32_t tagvalue;
  122. uint32_t tagclass;
  123. tagvalue = intx2uint32(&GetValue(ass, tag->Tag)->U.Integer.Value);
  124. tagclass = tag->Class; /* multiple of 0x40 */
  125. return (tagclass << 24) | tagvalue;
  126. }
  127. /* generate encoding of a tag */
  128. uint32_t GenBEREncTag(char *pszLenOffName, AssignmentList_t ass, BERTypeInfo_t *info, char *encref, char **tagref)
  129. {
  130. Tag_t *tag;
  131. uint32_t tagvalue;
  132. uint32_t neoc;
  133. char tagbuf[64];
  134. int first;
  135. neoc = 0;
  136. first = 1;
  137. if (*tagref)
  138. strcpy(tagbuf, *tagref);
  139. else
  140. strcpy(tagbuf, "0");
  141. /* we have to examine all tags */
  142. for (tag = info->Tags; tag; tag = tag ? tag->Next : NULL) {
  143. /* get value of tag */
  144. tagvalue = Tag2uint32(ass, tag);
  145. while (tag && tag->Type == eTagType_Implicit)
  146. tag = tag->Next;
  147. /* get tag */
  148. if (first && *tagref) {
  149. sprintf(tagbuf, "%s ? %s : 0x%x", *tagref, *tagref, tagvalue);
  150. } else {
  151. sprintf(tagbuf, "0x%x", tagvalue);
  152. }
  153. /* encode explicit tag */
  154. if (tag) {
  155. char szLenOff[24];
  156. sprintf(&szLenOff[0], "%s%u", pszLenOffName, neoc);
  157. outputvar("ASN1uint32_t %s;\n", &szLenOff[0]);
  158. output("if (!ASN1BEREncExplicitTag(%s, %s, &%s))\n", encref, tagbuf, &szLenOff[0]);
  159. output("return 0;\n");
  160. neoc++;
  161. strcpy(tagbuf, "0");
  162. }
  163. first = 0;
  164. }
  165. /* return last implicit tag */
  166. *tagref = strdup(tagbuf);
  167. return neoc;
  168. }
  169. /* generate encoding of end of tag */
  170. void
  171. GenBEREncTagEnd(char *pszLenOffName, uint32_t neoc, char *encref)
  172. {
  173. while (neoc--)
  174. {
  175. char szLenOff[24];
  176. sprintf(&szLenOff[0], "%s%u", pszLenOffName, neoc);
  177. outputvar("ASN1uint32_t %s;\n", &szLenOff[0]);
  178. output("if (!ASN1BEREncEndOfContents(%s, %s))\n", encref, &szLenOff[0]);
  179. output("return 0;\n");
  180. }
  181. }
  182. /* generate decoding of a tag */
  183. uint32_t
  184. GenBERDecTag(char *pszDecoderName, char *pszOctetPtrName, AssignmentList_t ass, BERTypeInfo_t *info, char **encref, char **tagref)
  185. {
  186. Tag_t *tag;
  187. uint32_t tagvalue;
  188. uint32_t depth;
  189. char encbuf[16];
  190. char tagbuf[64];
  191. int first;
  192. depth = 0;
  193. first = 1;
  194. if (*tagref)
  195. strcpy(tagbuf, *tagref);
  196. else
  197. strcpy(tagbuf, "0");
  198. /* we have to examine all tags */
  199. for (tag = info->Tags; tag; tag = tag ? tag->Next : NULL) {
  200. /* get value of tag */
  201. tagvalue = Tag2uint32(ass, tag);
  202. while (tag && tag->Type == eTagType_Implicit)
  203. tag = tag->Next;
  204. /* get tag */
  205. if (first && *tagref) {
  206. sprintf(tagbuf, "%s ? %s : 0x%x", *tagref, *tagref, tagvalue);
  207. } else {
  208. sprintf(tagbuf, "0x%x", tagvalue);
  209. }
  210. /* decode explicit tag */
  211. if (tag)
  212. {
  213. char szDecName[24];
  214. char szPtrName[24];
  215. sprintf(&szDecName[0], "%s%u", pszDecoderName, depth);
  216. sprintf(&szPtrName[0], "%s%u", pszOctetPtrName, depth);
  217. outputvar("ASN1decoding_t %s;\n",&szDecName[0]);
  218. outputvar("ASN1octet_t *%s;\n", &szPtrName[0]);
  219. output("if (!ASN1BERDecExplicitTag(%s, %s, &%s, &%s))\n",
  220. *encref, tagbuf, &szDecName[0], &szPtrName[0]);
  221. output("return 0;\n");
  222. *encref = strdup(&szDecName[0]);
  223. depth++;
  224. strcpy(tagbuf, "0");
  225. }
  226. first = 0;
  227. }
  228. /* return last implicit tag */
  229. *tagref = strdup(tagbuf);
  230. return depth;
  231. }
  232. /* generate decoding of end of tag */
  233. void
  234. GenBERDecTagEnd(char *pszDecoderName, char *pszOctetPtrName, uint32_t depth, char *encref)
  235. {
  236. char szDecName[24];
  237. char szPtrName[24];
  238. uint32_t i;
  239. for (i = 0; i < depth; i++)
  240. {
  241. sprintf(&szDecName[0], "%s%u", pszDecoderName, depth - i - 1);
  242. sprintf(&szPtrName[0], "%s%u", pszOctetPtrName, depth - i - 1);
  243. if (i != depth - 1)
  244. {
  245. output("if (!ASN1BERDecEndOfContents(%s%u, %s, %s))\n",
  246. pszDecoderName, depth - i - 2, &szDecName[0], &szPtrName[0]);
  247. }
  248. else
  249. {
  250. output("if (!ASN1BERDecEndOfContents(%s, %s, %s))\n",
  251. encref, &szDecName[0], &szPtrName[0]);
  252. }
  253. output("return 0;\n");
  254. }
  255. }
  256. /* generate function body for a type */
  257. void GenBERFuncType(AssignmentList_t ass, char *module, Assignment_t *at, TypeFunc_e et)
  258. {
  259. Type_t *type;
  260. char *encref;
  261. char *valref;
  262. /* get some informations */
  263. type = at->U.Type.Type;
  264. switch (et) {
  265. case eStringTable:
  266. valref = encref = "";
  267. break;
  268. case eEncode:
  269. encref = "enc";
  270. valref = "val";
  271. break;
  272. case eDecode:
  273. encref = "dec";
  274. valref = "val";
  275. break;
  276. }
  277. /* function body */
  278. switch (type->Type) {
  279. case eType_Boolean:
  280. case eType_Integer:
  281. case eType_Enumerated:
  282. case eType_Real:
  283. case eType_BitString:
  284. case eType_OctetString:
  285. case eType_UTF8String:
  286. case eType_Null:
  287. case eType_EmbeddedPdv:
  288. case eType_External:
  289. case eType_ObjectIdentifier:
  290. case eType_BMPString:
  291. case eType_GeneralString:
  292. case eType_GraphicString:
  293. case eType_IA5String:
  294. case eType_ISO646String:
  295. case eType_NumericString:
  296. case eType_PrintableString:
  297. case eType_TeletexString:
  298. case eType_T61String:
  299. case eType_UniversalString:
  300. case eType_VideotexString:
  301. case eType_VisibleString:
  302. case eType_CharacterString:
  303. case eType_GeneralizedTime:
  304. case eType_UTCTime:
  305. case eType_ObjectDescriptor:
  306. case eType_RestrictedString:
  307. case eType_Open:
  308. case eType_Reference:
  309. case eType_SequenceOf:
  310. case eType_SetOf:
  311. GenBERFuncSimpleType(ass, &type->BERTypeInfo, Dereference(valref), et, encref, "tag");
  312. break;
  313. case eType_Sequence:
  314. case eType_Set:
  315. case eType_InstanceOf:
  316. GenBERFuncSequenceSetType(ass, module, at, valref, encref, et, "tag");
  317. break;
  318. case eType_Choice:
  319. GenBERFuncChoiceType(ass, module, at, valref, encref, et, "tag");
  320. break;
  321. case eType_Selection:
  322. case eType_Undefined:
  323. MyAbort();
  324. /*NOTREACHED*/
  325. }
  326. }
  327. /* generate function body for components */
  328. void GenBERFuncComponents(AssignmentList_t ass, char *module, uint32_t optindex, ComponentList_t components, char *valref, char *encref, char *oref, TypeFunc_e et, BERTypeInfo_t *info, int *pfContainOpenTypeComWithDefTags)
  329. {
  330. BERSTIData_e data = info->Data;
  331. Component_t *com;
  332. NamedType_t *namedType;
  333. char *ide;
  334. int conditional, inextension;
  335. uint32_t flg;
  336. Tag_t *tags;
  337. unsigned int first_tag, last_tag;
  338. int fDefTags;
  339. int fOpenTypeComponent;
  340. char valbuf[256];
  341. char typebuf[256];
  342. *pfContainOpenTypeComWithDefTags = 0;
  343. /* emit components */
  344. inextension = 0;
  345. for (com = components; com; com = com->Next)
  346. {
  347. fDefTags = 0; // safety net
  348. fOpenTypeComponent = 0; // safety net
  349. /* check for extension marker */
  350. if (com->Type == eComponent_ExtensionMarker) {
  351. inextension = 1;
  352. /* update index into optional field for sequence/set */
  353. if (data != eBERSTIData_Choice)
  354. optindex = (optindex + 7) & ~7;
  355. continue;
  356. }
  357. /* get some information */
  358. namedType = com->U.NOD.NamedType;
  359. ide = Identifier2C(namedType->Identifier);
  360. /* check if optional/default component is present or choice is */
  361. /* selected*/
  362. conditional = 0;
  363. switch (et) {
  364. case eStringTable:
  365. break;
  366. case eEncode:
  367. if (data == eBERSTIData_Choice) {
  368. output("case %d:\n", optindex);
  369. conditional = 1;
  370. optindex++;
  371. } else {
  372. if (com->Type == eComponent_Optional ||
  373. com->Type == eComponent_Default ||
  374. inextension) {
  375. output("if (%s[%u] & 0x%x) {\n", oref,
  376. optindex / 8, 0x80 >> (optindex & 7));
  377. conditional = 1;
  378. optindex++;
  379. }
  380. }
  381. break;
  382. case eDecode:
  383. if (data == eBERSTIData_Sequence &&
  384. com->Type != eComponent_Optional &&
  385. com->Type != eComponent_Default &&
  386. !inextension)
  387. break;
  388. fOpenTypeComponent = IsComponentOpenType(com);
  389. if (fOpenTypeComponent)
  390. {
  391. const unsigned int c_nDefFirstTag = 0x80000001;
  392. const unsigned int c_nDefLastTag = 0x8000001f;
  393. unsigned int nTag = c_nDefFirstTag;
  394. tags = com->U.NOD.NamedType->Type->FirstTags;
  395. first_tag = Tag2uint32(ass, com->U.NOD.NamedType->Type->FirstTags);
  396. fDefTags = 1; // initial value
  397. while (tags->Next)
  398. {
  399. fDefTags = fDefTags && (Tag2uint32(ass, tags) == nTag++);
  400. tags = tags->Next;
  401. }
  402. last_tag = Tag2uint32(ass, tags);
  403. fDefTags = fDefTags && (c_nDefFirstTag == first_tag) && (c_nDefLastTag == last_tag);
  404. *pfContainOpenTypeComWithDefTags = *pfContainOpenTypeComWithDefTags || fDefTags;
  405. }
  406. if (data == eBERSTIData_Sequence)
  407. {
  408. if (fOpenTypeComponent)
  409. {
  410. outputvar("ASN1uint32_t t;\n");
  411. output("if (ASN1BERDecPeekTag(%s, &t)) {\n", encref);
  412. }
  413. else
  414. {
  415. outputvar("ASN1uint32_t t;\n");
  416. output("ASN1BERDecPeekTag(%s, &t);\n", encref);
  417. }
  418. if (! fDefTags)
  419. {
  420. output("if (");
  421. }
  422. flg = 0;
  423. }
  424. if (eBERSTIData_Sequence == data && fDefTags && fOpenTypeComponent)
  425. {
  426. #if 0
  427. if (first_tag == last_tag)
  428. {
  429. output("0x%x == t", first_tag);
  430. }
  431. else
  432. {
  433. output("0x%x <= t && t <= 0x%x", first_tag, last_tag);
  434. }
  435. #endif
  436. conditional = 1;
  437. }
  438. else
  439. if (eBERSTIData_Set == data && fDefTags && fOpenTypeComponent)
  440. {
  441. output("default:\n");
  442. #if 1
  443. if (info->Flags & eTypeFlags_ExtensionMarker)
  444. {
  445. output("#error \"Untagged open type cannot be in the SET construct with an extension mark.\nPlease manually fix the source code.\"");
  446. output("ASSERT(0); /* Untagged open type cannot be in the SET construct with an extension mark */\n");
  447. output("if (1) {\n");
  448. }
  449. #else
  450. if (first_tag == last_tag)
  451. {
  452. output("if (0x%x == t) {\n", first_tag);
  453. }
  454. else
  455. {
  456. output("if (0x%x <= t && t <= 0x%x) {\n", first_tag, last_tag);
  457. }
  458. #endif
  459. conditional = 1;
  460. }
  461. else
  462. if (eBERSTIData_Choice == data && fDefTags && fOpenTypeComponent)
  463. {
  464. output("default:\n");
  465. #if 1
  466. if (info->Flags & eTypeFlags_ExtensionMarker)
  467. {
  468. output("#error \"Untagged open type cannot be in the CHOICE construct with an extension mark.\nPlease manually fix the source code.\"");
  469. output("ASSERT(0); /* Untagged open type cannot be in the CHOICE construct with an extension mark */\n");
  470. output("if (1) {\n");
  471. }
  472. #else
  473. if (first_tag == last_tag)
  474. {
  475. output("if (0x%x == t) {\n", first_tag);
  476. }
  477. else
  478. {
  479. output("if (0x%x <= t && t <= 0x%x) {\n", first_tag, last_tag);
  480. }
  481. #endif
  482. conditional = 1;
  483. }
  484. else
  485. {
  486. for (tags = com->U.NOD.NamedType->Type->FirstTags; tags; tags = tags->Next)
  487. {
  488. switch (data)
  489. {
  490. case eBERSTIData_Choice:
  491. output("case 0x%x:\n", Tag2uint32(ass, tags));
  492. break;
  493. case eBERSTIData_Set:
  494. output("case 0x%x:\n", Tag2uint32(ass, tags));
  495. break;
  496. case eBERSTIData_Sequence:
  497. if (flg)
  498. output(" || ");
  499. output("t == 0x%x", Tag2uint32(ass, tags));
  500. flg = 1;
  501. break;
  502. default:
  503. if (flg)
  504. output(" || ");
  505. output("t == 0x%x", Tag2uint32(ass, tags));
  506. flg = 1;
  507. break;
  508. }
  509. }
  510. }
  511. if (data == eBERSTIData_Choice) {
  512. output("(%s)->choice = %d;\n", valref, optindex);
  513. conditional = 1;
  514. optindex++;
  515. break;
  516. } else {
  517. if (data == eBERSTIData_Sequence)
  518. {
  519. if (! fDefTags)
  520. {
  521. output(") {\n");
  522. }
  523. }
  524. if (com->Type == eComponent_Optional ||
  525. com->Type == eComponent_Default ||
  526. inextension) {
  527. output("%s[%u] |= 0x%x;\n", oref,
  528. optindex / 8, 0x80 >> (optindex & 7));
  529. optindex++;
  530. }
  531. conditional = 1;
  532. }
  533. break;
  534. }
  535. /* dereference pointer if pointer directive used */
  536. if (data == eBERSTIData_Choice) {
  537. if (GetTypeRules(ass, namedType->Type) & eTypeRules_Pointer)
  538. sprintf(valbuf, "*(%s)->u.%s", valref, ide);
  539. else
  540. sprintf(valbuf, "(%s)->u.%s", valref, ide);
  541. } else {
  542. if (GetTypeRules(ass, namedType->Type) & eTypeRules_Pointer)
  543. sprintf(valbuf, "*(%s)->%s", valref, ide);
  544. else
  545. sprintf(valbuf, "(%s)->%s", valref, ide);
  546. }
  547. /* allocate memory if decoding and pointer directive used */
  548. if (et == eDecode &&
  549. (GetTypeRules(ass, namedType->Type) & eTypeRules_Pointer) &&
  550. !(GetType(ass, namedType->Type)->Flags & eTypeFlags_Null)) {
  551. sprintf(typebuf, "%s *",
  552. GetTypeName(ass, namedType->Type));
  553. output("if (!(%s = (%s)ASN1DecAlloc(%s, sizeof(%s))))\n",
  554. Reference(valbuf), typebuf, encref, valbuf);
  555. output("return 0;\n");
  556. }
  557. /* handle subtype value */
  558. GenBERFuncSimpleType(ass, &namedType->Type->BERTypeInfo,
  559. valbuf, et, encref, NULL);
  560. if (eDecode == et && fOpenTypeComponent)
  561. {
  562. if (eBERSTIData_Set == data && fDefTags)
  563. {
  564. if (info->Flags & eTypeFlags_ExtensionMarker)
  565. {
  566. output("} else {\n");
  567. output("if (!ASN1BERDecSkip(%s))\n", encref);
  568. output("return 0;\n");
  569. output("}\n");
  570. }
  571. }
  572. else
  573. if (eBERSTIData_Sequence == data)
  574. {
  575. if (! fDefTags)
  576. {
  577. output("}\n");
  578. }
  579. }
  580. }
  581. /* end of check for presence of optional/default component */
  582. if (data == eBERSTIData_Set && et == eDecode ||
  583. data == eBERSTIData_Choice)
  584. {
  585. if (conditional)
  586. output("break;\n");
  587. }
  588. else
  589. {
  590. if (conditional)
  591. output("}\n");
  592. }
  593. }
  594. }
  595. /* generate function body for sequence/set type */
  596. void
  597. GenBERFuncSequenceSetType(AssignmentList_t ass, char *module, Assignment_t *at, char *valref, char *encref, TypeFunc_e et, char *tagref)
  598. {
  599. Type_t *type = at->U.Type.Type;
  600. BERTypeInfo_t *info = &type->BERTypeInfo;
  601. uint32_t optionals, extensions;
  602. ComponentList_t components;
  603. char *oldencref;
  604. char *oldencref2;
  605. uint32_t neoc, depth;
  606. int fContainOpenTypeComWithDefTags = 0;
  607. char obuf[256];
  608. optionals = type->U.SSC.Optionals;
  609. extensions = type->U.SSC.Extensions;
  610. components = type->U.SSC.Components;
  611. /* handle tag and length */
  612. switch (et) {
  613. case eEncode:
  614. neoc = GenBEREncTag(LEN_OFFSET_STR2, ass, info, encref, &tagref);
  615. outputvar("ASN1uint32_t %s;\n", LEN_OFFSET_STR);
  616. output("if (!ASN1BEREncExplicitTag(%s, %s, &%s))\n", encref, tagref, LEN_OFFSET_STR);
  617. output("return 0;\n");
  618. // neoc++;
  619. break;
  620. case eDecode:
  621. outputvar("ASN1decoding_t dd;\n");
  622. outputvar("ASN1octet_t *di;\n");
  623. oldencref = encref;
  624. depth = GenBERDecTag(DECODER_NAME2, STREAM_END_NAME2, ass, info, &encref, &tagref);
  625. oldencref2 = encref;
  626. output("if (!ASN1BERDecExplicitTag(%s, %s, &dd, &di))\n",
  627. encref, tagref);
  628. output("return 0;\n");
  629. encref = "dd";
  630. if (optionals || extensions)
  631. output("ZeroMemory((%s)->o, %d);\n", valref,
  632. (optionals + 7) / 8 + (extensions + 7) / 8);
  633. break;
  634. }
  635. /* set/clear missing bits in optional/default bit field */
  636. GenFuncSequenceSetOptionals(ass, valref, components, optionals, extensions,
  637. obuf, et);
  638. /* create switch statement */
  639. if (et == eDecode) {
  640. switch (info->Data) {
  641. case eBERSTIData_Set:
  642. outputvar("ASN1uint32_t t;\n");
  643. output("while (ASN1BERDecNotEndOfContents(%s, di)) {\n", encref);
  644. output("if (!ASN1BERDecPeekTag(%s, &t))\n", encref);
  645. output("return 0;\n");
  646. output("switch (t) {\n");
  647. break;
  648. }
  649. }
  650. /* emit components */
  651. GenBERFuncComponents(ass, module, 0, components,
  652. valref, encref, obuf, et, info, &fContainOpenTypeComWithDefTags);
  653. /* end of switch statement */
  654. if (et == eDecode) {
  655. switch (info->Data) {
  656. case eBERSTIData_Set:
  657. // if (NULL == FindOpenTypeComponent(components))
  658. if (! fContainOpenTypeComWithDefTags)
  659. {
  660. output("default:\n");
  661. if (info->Flags & eTypeFlags_ExtensionMarker) {
  662. output("if (!ASN1BERDecSkip(%s))\n", encref);
  663. output("return 0;\n");
  664. output("break;\n");
  665. } else {
  666. output("ASN1DecSetError(%s, ASN1_ERR_CORRUPT);\n", encref);
  667. output("return 0;\n");
  668. }
  669. }
  670. output("}\n");
  671. output("}\n");
  672. break;
  673. }
  674. }
  675. /* some user-friendly assignments for non-present optional/default */
  676. /* components */
  677. GenFuncSequenceSetDefaults(ass, valref, components, obuf, et);
  678. /* generate end of contents */
  679. switch (et) {
  680. case eEncode:
  681. /* encode the end-of-contents octets */
  682. output("if (!ASN1BEREncEndOfContents(%s, %s))\n", encref, LEN_OFFSET_STR);
  683. output("return 0;\n");
  684. GenBEREncTagEnd(LEN_OFFSET_STR2, neoc, encref);
  685. break;
  686. case eDecode:
  687. if ((info->Flags & eTypeFlags_ExtensionMarker) &&
  688. info->Data != eBERSTIData_Set) {
  689. output("while (ASN1BERDecNotEndOfContents(%s, di)) {\n", encref);
  690. output("if (!ASN1BERDecSkip(%s))\n", encref);
  691. output("return 0;\n");
  692. output("}\n");
  693. }
  694. output("if (!ASN1BERDecEndOfContents(%s, dd, di))\n", oldencref2);
  695. output("return 0;\n");
  696. GenBERDecTagEnd(DECODER_NAME2, STREAM_END_NAME2, depth, oldencref);
  697. break;
  698. }
  699. }
  700. /* generate function body for choice type */
  701. // lonchanc: we should re-visit the work about ASN1_CHOICE_BASE.
  702. // the change for BER is not complete!!! BUGBUG
  703. void
  704. GenBERFuncChoiceType(AssignmentList_t ass, char *module, Assignment_t *at, char *valref, char *encref, TypeFunc_e et, char *tagref)
  705. {
  706. Type_t *type;
  707. BERTypeInfo_t *info;
  708. Component_t *components, *c;
  709. uint32_t neoc, depth;
  710. char *oldencref;
  711. uint32_t ncomponents;
  712. int fContainOpenTypeComWithDefTags = 0;
  713. /* get some informations */
  714. type = at->U.Type.Type;
  715. info = &type->BERTypeInfo;
  716. components = type->U.SSC.Components;
  717. for (c = components, ncomponents = 0; c; c = c->Next) {
  718. switch (c->Type) {
  719. case eComponent_Normal:
  720. ncomponents++;
  721. break;
  722. }
  723. }
  724. /* encode explicit tags */
  725. switch (et) {
  726. case eEncode:
  727. neoc = GenBEREncTag(LEN_OFFSET_STR2, ass, info, encref, &tagref);
  728. break;
  729. case eDecode:
  730. oldencref = encref;
  731. depth = GenBERDecTag(DECODER_NAME2, STREAM_END_NAME2, ass, info, &encref, &tagref);
  732. break;
  733. }
  734. /* create switch statement */
  735. switch (et) {
  736. case eStringTable:
  737. break;
  738. case eEncode:
  739. output("switch ((%s)->choice) {\n", valref);
  740. break;
  741. case eDecode:
  742. outputvar("ASN1uint32_t t;\n");
  743. output("if (!ASN1BERDecPeekTag(%s, &t))\n", encref);
  744. output("return 0;\n");
  745. output("switch (t) {\n");
  746. break;
  747. }
  748. /* generate components */
  749. GenBERFuncComponents(ass, module, ASN1_CHOICE_BASE, components,
  750. valref, encref, NULL, et, info, &fContainOpenTypeComWithDefTags);
  751. /* end of switch statement */
  752. switch (et) {
  753. case eStringTable:
  754. break;
  755. case eEncode:
  756. output("}\n");
  757. break;
  758. case eDecode:
  759. if (fContainOpenTypeComWithDefTags)
  760. {
  761. if (info->Flags & eTypeFlags_ExtensionMarker)
  762. {
  763. output("} else {\n");
  764. output("(%s)->choice = %d;\n", valref, ASN1_CHOICE_BASE + ncomponents); /* unknown extens.*/
  765. output("if (!ASN1BERDecSkip(%s))\n", encref);
  766. output("return 0;\n");
  767. output("}\n");
  768. output("break;\n");
  769. }
  770. }
  771. else
  772. {
  773. output("default:\n");
  774. if (info->Flags & eTypeFlags_ExtensionMarker) {
  775. output("(%s)->choice = %d;\n", valref, ASN1_CHOICE_BASE + ncomponents); /* unknown extens.*/
  776. output("if (!ASN1BERDecSkip(%s))\n", encref);
  777. output("return 0;\n");
  778. output("break;\n");
  779. } else {
  780. output("ASN1DecSetError(%s, ASN1_ERR_CORRUPT);\n", encref);
  781. output("return 0;\n");
  782. }
  783. }
  784. output("}\n");
  785. break;
  786. }
  787. /* generate end of contents */
  788. switch (et) {
  789. case eEncode:
  790. GenBEREncTagEnd(LEN_OFFSET_STR2, neoc, encref);
  791. break;
  792. case eDecode:
  793. GenBERDecTagEnd(DECODER_NAME2, STREAM_END_NAME2, depth, oldencref);
  794. }
  795. }
  796. /* generate function body for simple type */
  797. void
  798. GenBERFuncSimpleType(AssignmentList_t ass, BERTypeInfo_t *info, char *valref, TypeFunc_e et, char *encref, char *tagref)
  799. {
  800. switch (et) {
  801. case eStringTable:
  802. break;
  803. case eEncode:
  804. GenBEREncSimpleType(ass, info, valref, encref, tagref);
  805. break;
  806. case eDecode:
  807. GenBERDecSimpleType(ass, info, valref, encref, tagref);
  808. break;
  809. }
  810. }
  811. /* generate encoding statements for a simple value */
  812. void
  813. GenBEREncSimpleType(AssignmentList_t ass, BERTypeInfo_t *info, char *valref, char *encref, char *tagref)
  814. {
  815. char *lenref;
  816. char lenbuf[256], valbuf[256];
  817. BERTypeInfo_t inf;
  818. inf = *info;
  819. /* examine type for special handling */
  820. switch (inf.Data) {
  821. case eBERSTIData_BitString:
  822. case eBERSTIData_RZBBitString:
  823. case eBERSTIData_OctetString:
  824. case eBERSTIData_UTF8String:
  825. case eBERSTIData_String:
  826. /* length and value of bit string, octet string and string */
  827. if (*valref != '*')
  828. {
  829. sprintf(lenbuf, "(%s).length", valref);
  830. sprintf(valbuf, "(%s).value", valref);
  831. }
  832. else
  833. {
  834. sprintf(lenbuf, "(%s)->length", Reference(valref));
  835. sprintf(valbuf, "(%s)->value", Reference(valref));
  836. }
  837. lenref = lenbuf;
  838. valref = valbuf;
  839. /* check for remove-zero-bits bit string */
  840. if (inf.Data == eBERSTIData_RZBBitString) {
  841. outputvar("ASN1uint32_t r;\n");
  842. output("r = %s;\n", lenref);
  843. output("ASN1BEREncRemoveZeroBits(&r, %s);\n",
  844. valref);
  845. lenref = "r";
  846. }
  847. break;
  848. case eBERSTIData_SequenceOf:
  849. case eBERSTIData_SetOf:
  850. if (inf.Rules & eTypeRules_PointerArrayMask)
  851. {
  852. /* length and value of sequence of/set of value with */
  853. /* length-pointer representation */
  854. sprintf(lenbuf, "(%s)->count", Reference(valref));
  855. sprintf(valbuf, "(%s)->value", Reference(valref));
  856. lenref = lenbuf;
  857. valref = valbuf;
  858. }
  859. else
  860. if (inf.Rules & eTypeRules_LinkedListMask)
  861. {
  862. lenref = "t";
  863. }
  864. else
  865. {
  866. MyAbort();
  867. }
  868. break;
  869. case eBERSTIData_ZeroString:
  870. /* length of a zero-terminated string value */
  871. outputvar("ASN1uint32_t t;\n");
  872. output("t = lstrlenA(%s);\n", valref);
  873. lenref = "t";
  874. break;
  875. case eBERSTIData_Boolean:
  876. if (g_fCaseBasedOptimizer)
  877. {
  878. if (BerOptCase_IsBoolean(&inf))
  879. {
  880. break;
  881. }
  882. }
  883. /* value of a boolean value */
  884. sprintf(valbuf, "(%s) ? 255 : 0", valref);
  885. valref = valbuf;
  886. inf.Data = eBERSTIData_Unsigned;
  887. break;
  888. default:
  889. /* other values have no additional length */
  890. lenref = NULL;
  891. break;
  892. }
  893. /* generate the encoding of the value */
  894. GenBEREncGenericUnextended(ass, &inf, valref, lenref, encref, tagref);
  895. }
  896. /* generate encoding statements for a simple value (after some special */
  897. /* handling has been done) */
  898. void
  899. GenBEREncGenericUnextended(AssignmentList_t ass, BERTypeInfo_t *info, char *valref, char *lenref, char *encref, char *tagref)
  900. {
  901. uint32_t neoc;
  902. char *p;
  903. char valbuf[256];
  904. /* encode tags */
  905. neoc = GenBEREncTag(LEN_OFFSET_STR, ass, info, encref, &tagref);
  906. /* encode length and value */
  907. switch (info->Data) {
  908. case eBERSTIData_Null:
  909. /* encode null value */
  910. output("if (!ASN1BEREncNull(%s, %s))\n", encref, tagref);
  911. output("return 0;\n");
  912. break;
  913. case eBERSTIData_Unsigned:
  914. case eBERSTIData_Integer:
  915. /* encode integer value; check for intx_t representation */
  916. if (info->NOctets) {
  917. if (info->Data == eBERSTIData_Unsigned) {
  918. output("if (!ASN1BEREncU32(%s, %s, %s))\n",
  919. encref, tagref, valref);
  920. } else {
  921. output("if (!ASN1BEREncS32(%s, %s, %s))\n",
  922. encref, tagref, valref);
  923. }
  924. output("return 0;\n");
  925. } else {
  926. output("if (!ASN1BEREncSX(%s, %s, %s))\n",
  927. encref, tagref, Reference(valref));
  928. output("return 0;\n");
  929. }
  930. break;
  931. case eBERSTIData_Real:
  932. /* encode real value; check for real_t representation */
  933. if (info->NOctets)
  934. output("if (!ASN1BEREncDouble(%s, %s, %s))\n",
  935. encref, tagref, valref);
  936. else
  937. output("if (!ASN1BEREncReal(%s, %s, %s))\n",
  938. encref, tagref, Reference(valref));
  939. output("return 0;\n");
  940. break;
  941. case eBERSTIData_BitString:
  942. case eBERSTIData_RZBBitString:
  943. /* encode bit string value */
  944. output("if (!ASN1%cEREncBitString(%s, %s, %s, %s))\n",
  945. g_eSubEncodingRule, encref, tagref, lenref, valref);
  946. output("return 0;\n");
  947. break;
  948. case eBERSTIData_OctetString:
  949. /* encode octet string value */
  950. output("if (!ASN1%cEREncOctetString(%s, %s, %s, %s))\n",
  951. g_eSubEncodingRule, encref, tagref, lenref, valref);
  952. output("return 0;\n");
  953. break;
  954. case eBERSTIData_UTF8String:
  955. /* encode octet string value */
  956. output("if (!ASN1%cEREncUTF8String(%s, %s, %s, %s))\n",
  957. g_eSubEncodingRule, encref, tagref, lenref, valref);
  958. output("return 0;\n");
  959. break;
  960. case eBERSTIData_SetOf:
  961. /* encoding of a set of value */
  962. if (eSubEncoding_Canonical == g_eSubEncodingRule ||
  963. eSubEncoding_Distinguished == g_eSubEncodingRule)
  964. {
  965. /* encoding of a set of value for DER/CER */
  966. /* lists will require an additional iterator */
  967. if (info->Rules &
  968. (eTypeRules_SinglyLinkedList | eTypeRules_DoublyLinkedList))
  969. {
  970. outputvar("P%s f;\n", info->Identifier);
  971. }
  972. /* encode the tag and infinite-length first */
  973. outputvar("ASN1uint32_t %s;\n", LEN_OFFSET_STR);
  974. output("if (!ASN1BEREncExplicitTag(%s, %s, &%s))\n", encref, tagref, LEN_OFFSET_STR);
  975. output("return 0;\n");
  976. /* create the SetOf block */
  977. outputvar("void *pBlk;\n");
  978. output("if (!ASN1DEREncBeginBlk(%s, ASN1_DER_SET_OF_BLOCK, &pBlk))\n", encref);
  979. output("return 0;\n");
  980. /* encode all elements */
  981. /* get the name of the elements */
  982. /* advance the iterator for lists */
  983. if (info->Rules & eTypeRules_PointerArrayMask)
  984. {
  985. outputvar("ASN1uint32_t i;\n");
  986. output("for (i = 0; i < %s; i++) {\n", lenref);
  987. sprintf(valbuf, "(%s)[i]", valref);
  988. }
  989. else if (info->Rules & eTypeRules_LinkedListMask)
  990. {
  991. output("for (f = %s; f; f = f->next) {\n", valref);
  992. sprintf(valbuf, "f->value");
  993. }
  994. else
  995. {
  996. MyAbort();
  997. }
  998. /* create the secondary encoder structure */
  999. outputvar("ASN1encoding_t enc2;\n");
  1000. output("if (!ASN1DEREncNewBlkElement(pBlk, &enc2))\n");
  1001. output("return 0;\n");
  1002. /* encode the element */
  1003. GenBERFuncSimpleType(ass, &info->SubType->BERTypeInfo, valbuf,
  1004. eEncode, "enc2", NULL);
  1005. /* create the secondary encoder structure */
  1006. output("if (!ASN1DEREncFlushBlkElement(pBlk))\n");
  1007. output("return 0;\n");
  1008. /* end of loop */
  1009. output("}\n");
  1010. /* create the secondary encoder structure */
  1011. output("if (!ASN1DEREncEndBlk(pBlk))\n");
  1012. output("return 0;\n");
  1013. /* encode the end-of-contents octets */
  1014. output("if (!ASN1BEREncEndOfContents(%s, %s))\n", encref, LEN_OFFSET_STR);
  1015. output("return 0;\n");
  1016. break;
  1017. }
  1018. /*FALLTHROUGH*/
  1019. case eBERSTIData_SequenceOf:
  1020. /* encoding of a sequence of value */
  1021. /* lists will require an additional iterator */
  1022. if (info->Rules & eTypeRules_LinkedListMask)
  1023. {
  1024. outputvar("P%s f;\n", info->Identifier);
  1025. }
  1026. /* encode the tag and infinite-length first */
  1027. outputvar("ASN1uint32_t %s;\n", LEN_OFFSET_STR);
  1028. output("if (!ASN1BEREncExplicitTag(%s, %s, &%s))\n", encref, tagref, LEN_OFFSET_STR);
  1029. output("return 0;\n");
  1030. /* encode all elements */
  1031. /* get the name of the elements */
  1032. /* advance the iterator for lists */
  1033. if (info->Rules & eTypeRules_PointerArrayMask)
  1034. {
  1035. outputvar("ASN1uint32_t i;\n");
  1036. output("for (i = 0; i < %s; i++) {\n", lenref);
  1037. sprintf(valbuf, "(%s)[i]", valref);
  1038. }
  1039. else if (info->Rules & eTypeRules_LinkedListMask)
  1040. {
  1041. output("for (f = %s; f; f = f->next) {\n", valref);
  1042. sprintf(valbuf, "f->value");
  1043. }
  1044. else
  1045. {
  1046. MyAbort();
  1047. }
  1048. /* encode the element */
  1049. GenBERFuncSimpleType(ass, &info->SubType->BERTypeInfo, valbuf,
  1050. eEncode, encref, NULL);
  1051. /* end of loop */
  1052. output("}\n");
  1053. /* encode the end-of-contents octets */
  1054. output("if (!ASN1BEREncEndOfContents(%s, %s))\n", encref, LEN_OFFSET_STR);
  1055. output("return 0;\n");
  1056. break;
  1057. case eBERSTIData_ObjectIdentifier:
  1058. /* encode an object identifier value */
  1059. if (info->pPrivateDirectives->fOidArray || g_fOidArray)
  1060. {
  1061. output("if (!ASN1BEREncObjectIdentifier2(%s, %s, %s))\n",
  1062. encref, tagref, Reference(valref));
  1063. }
  1064. else
  1065. {
  1066. output("if (!ASN1BEREncObjectIdentifier(%s, %s, %s))\n",
  1067. encref, tagref, Reference(valref));
  1068. }
  1069. output("return 0;\n");
  1070. break;
  1071. case eBERSTIData_ObjectIdEncoded:
  1072. /* encode an encoded object identifier value */
  1073. output("if (!ASN1BEREncEoid(%s, %s, %s))\n",
  1074. encref, tagref, Reference(valref));
  1075. output("return 0;\n");
  1076. break;
  1077. case eBERSTIData_String:
  1078. case eBERSTIData_ZeroString:
  1079. /* encode a string value */
  1080. if (info->NOctets == 1) {
  1081. p = "Char";
  1082. } else if (info->NOctets == 2) {
  1083. p = "Char16";
  1084. } else if (info->NOctets == 4) {
  1085. p = "Char32";
  1086. } else
  1087. MyAbort();
  1088. output("if (!ASN1%cEREnc%sString(%s, %s, %s, %s))\n",
  1089. g_eSubEncodingRule, p, encref, tagref, lenref, valref);
  1090. output("return 0;\n");
  1091. break;
  1092. case eBERSTIData_External:
  1093. /* encode an external value */
  1094. output("if (!ASN1BEREncExternal(%s, %s, %s))\n",
  1095. encref, tagref, Reference(valref));
  1096. output("return 0;\n");
  1097. break;
  1098. case eBERSTIData_EmbeddedPdv:
  1099. /* encode an embedded pdv value */
  1100. output("if (!ASN1BEREncEmbeddedPdv(%s, %s, %s))\n",
  1101. encref, tagref, Reference(valref));
  1102. output("return 0;\n");
  1103. break;
  1104. case eBERSTIData_MultibyteString:
  1105. /* encode a multibyte string value */
  1106. if (info->Rules & eTypeRules_LengthPointer)
  1107. {
  1108. output("if (!ASN1%cEREncMultibyteString(%s, %s, %s))\n",
  1109. g_eSubEncodingRule, encref, tagref, Reference(valref));
  1110. }
  1111. else
  1112. {
  1113. output("if (!ASN1%cEREncZeroMultibyteString(%s, %s, %s))\n",
  1114. g_eSubEncodingRule, encref, tagref, valref);
  1115. }
  1116. output("return 0;\n");
  1117. break;
  1118. case eBERSTIData_UnrestrictedString:
  1119. /* encode an character string value */
  1120. output("if (!ASN1BEREncCharacterString(%s, %s, %s))\n",
  1121. encref, tagref, Reference(valref));
  1122. output("return 0;\n");
  1123. break;
  1124. case eBERSTIData_GeneralizedTime:
  1125. /* encode a generalized time value */
  1126. output("if (!ASN1%cEREncGeneralizedTime(%s, %s, %s))\n",
  1127. g_eSubEncodingRule, encref, tagref, Reference(valref));
  1128. output("return 0;\n");
  1129. break;
  1130. case eBERSTIData_UTCTime:
  1131. /* encode a utc time value */
  1132. output("if (!ASN1%cEREncUTCTime(%s, %s, %s))\n",
  1133. g_eSubEncodingRule, encref, tagref, Reference(valref));
  1134. output("return 0;\n");
  1135. break;
  1136. case eBERSTIData_Open:
  1137. /* encode an open type value */
  1138. output("if (!ASN1BEREncOpenType(%s, %s))\n",
  1139. encref, Reference(valref));
  1140. output("return 0;\n");
  1141. break;
  1142. case eBERSTIData_Reference:
  1143. /* call other encoding function for reference types */
  1144. output("if (!ASN1Enc_%s(%s, %s, %s))\n",
  1145. Identifier2C(info->SubIdentifier),
  1146. encref, tagref, Reference(valref));
  1147. output("return 0;\n");
  1148. break;
  1149. case eBERSTIData_Boolean:
  1150. if (g_fCaseBasedOptimizer)
  1151. {
  1152. output("if (!ASN1BEREncBool(%s, %s, %s))\n", encref, tagref, valref);
  1153. output("return 0;\n");
  1154. }
  1155. break;
  1156. }
  1157. /* encode the end of tag octets */
  1158. GenBEREncTagEnd(LEN_OFFSET_STR, neoc, encref);
  1159. }
  1160. /* generate decoding statements for a simple value */
  1161. void
  1162. GenBERDecSimpleType(AssignmentList_t ass, BERTypeInfo_t *info, char *valref, char *encref, char *tagref)
  1163. {
  1164. char valbuf[256], lenbuf[256];
  1165. char *lenref;
  1166. BERTypeInfo_t inf;
  1167. inf = *info;
  1168. /* examine type for special handling */
  1169. switch (inf.Data) {
  1170. case eBERSTIData_SequenceOf:
  1171. case eBERSTIData_SetOf:
  1172. if (inf.Rules & eTypeRules_PointerArrayMask)
  1173. {
  1174. /* length and value of sequence of/set of value with */
  1175. /* length-pointer representation */
  1176. sprintf(lenbuf, "(%s)->count", Reference(valref));
  1177. sprintf(valbuf, "(%s)->value", Reference(valref));
  1178. lenref = lenbuf;
  1179. valref = valbuf;
  1180. }
  1181. else
  1182. if (inf.Rules & eTypeRules_LinkedListMask)
  1183. {
  1184. /* use a loop for sequence of/set of value with */
  1185. /* list representation */
  1186. outputvar("P%s *f;\n", inf.Identifier);
  1187. lenref = NULL;
  1188. }
  1189. else
  1190. {
  1191. MyAbort();
  1192. }
  1193. break;
  1194. case eBERSTIData_Boolean:
  1195. if (g_fCaseBasedOptimizer)
  1196. {
  1197. if (BerOptCase_IsBoolean(&inf))
  1198. {
  1199. break;
  1200. }
  1201. }
  1202. /* boolean value */
  1203. inf.Data = eBERSTIData_Unsigned;
  1204. lenref = NULL;
  1205. break;
  1206. default:
  1207. /* other values have no additional length */
  1208. lenref = NULL;
  1209. break;
  1210. }
  1211. /* generate the decoding of the value */
  1212. GenBERDecGenericUnextended(ass, &inf, valref, lenref, encref, tagref);
  1213. }
  1214. /* generate decoding statements for a simple value (after some special */
  1215. /* handling has been done) */
  1216. void
  1217. GenBERDecGenericUnextended(AssignmentList_t ass, BERTypeInfo_t *info, char *valref, char *lenref, char *encref, char *tagref)
  1218. {
  1219. uint32_t depth;
  1220. char *p;
  1221. char *oldencref;
  1222. char *oldencref2;
  1223. char valbuf[256];
  1224. /* decode tags */
  1225. oldencref = encref;
  1226. depth = GenBERDecTag(DECODER_NAME, STREAM_END_NAME, ass, info, &encref, &tagref);
  1227. /* decode length and value */
  1228. switch (info->Data) {
  1229. case eBERSTIData_Null:
  1230. /* decode null value */
  1231. output("if (!ASN1BERDecNull(%s, %s))\n", encref, tagref);
  1232. output("return 0;\n");
  1233. break;
  1234. case eBERSTIData_Integer:
  1235. /* decode integer value; check for intx_t representation */
  1236. if (!info->NOctets) {
  1237. output("if (!ASN1BERDecSXVal(%s, %s, %s))\n",
  1238. encref, tagref, Reference(valref));
  1239. output("return 0;\n");
  1240. } else {
  1241. output("if (!ASN1BERDecS%dVal(%s, %s, %s))\n",
  1242. info->NOctets * 8, encref, tagref, Reference(valref));
  1243. output("return 0;\n");
  1244. }
  1245. break;
  1246. case eBERSTIData_Unsigned:
  1247. if (!info->NOctets) {
  1248. output("if (!ASN1BERDecSXVal(%s, %s, %s))\n",
  1249. encref, tagref, Reference(valref));
  1250. output("return 0;\n");
  1251. } else {
  1252. unsigned long cBits = info->NOctets * 8;
  1253. if (32 == cBits)
  1254. {
  1255. output("if (!ASN1BERDecU32Val(%s, %s, (ASN1uint32_t *) %s))\n",
  1256. encref, tagref, Reference(valref));
  1257. }
  1258. else
  1259. {
  1260. output("if (!ASN1BERDecU%uVal(%s, %s, %s))\n",
  1261. cBits, encref, tagref, Reference(valref));
  1262. }
  1263. output("return 0;\n");
  1264. }
  1265. break;
  1266. case eBERSTIData_Real:
  1267. /* decode real value; check for real_t representation */
  1268. if (info->NOctets)
  1269. output("if (!ASN1BERDecDouble(%s, %s, %s))\n",
  1270. encref, tagref, Reference(valref));
  1271. else
  1272. output("if (!ASN1BERDecReal(%s, %s, %s))\n",
  1273. encref, tagref, Reference(valref));
  1274. output("return 0;\n");
  1275. break;
  1276. case eBERSTIData_BitString:
  1277. case eBERSTIData_RZBBitString:
  1278. /* decode bit string value */
  1279. output("if (!ASN1BERDecBitString%s(%s, %s, %s))\n",
  1280. info->pPrivateDirectives->fNoMemCopy ? "2" : "",
  1281. encref, tagref, Reference(valref));
  1282. output("return 0;\n");
  1283. break;
  1284. case eBERSTIData_OctetString:
  1285. /* decode octet string value */
  1286. output("if (!ASN1BERDecOctetString%s(%s, %s, %s))\n",
  1287. info->pPrivateDirectives->fNoMemCopy ? "2" : "",
  1288. encref, tagref, Reference(valref));
  1289. output("return 0;\n");
  1290. break;
  1291. case eBERSTIData_UTF8String:
  1292. /* decode octet string value */
  1293. output("if (!ASN1BERDecUTF8String(%s, %s, %s))\n",
  1294. encref, tagref, Reference(valref));
  1295. output("return 0;\n");
  1296. break;
  1297. case eBERSTIData_SetOf:
  1298. case eBERSTIData_SequenceOf:
  1299. /* encoding of a set of/sequence of value */
  1300. outputvar("ASN1decoding_t dd;\n");
  1301. outputvar("ASN1octet_t *di;\n");
  1302. /* decode the tag and length first */
  1303. output("if (!ASN1BERDecExplicitTag(%s, %s, &dd, &di))\n",
  1304. encref, tagref);
  1305. output("return 0;\n");
  1306. oldencref2 = encref;
  1307. encref = "dd";
  1308. outputvar("ASN1uint32_t t;\n");
  1309. if (info->Rules & eTypeRules_LengthPointer)
  1310. {
  1311. /* get length and value of sequence of/set of value with */
  1312. /* length-pointer representation */
  1313. outputvar("ASN1uint32_t n;\n");
  1314. output("%s = n = 0;\n", lenref);
  1315. output("%s = NULL;\n", valref);
  1316. }
  1317. else
  1318. if (info->Rules & eTypeRules_FixedArray)
  1319. {
  1320. /* get length and value of sequence of/set of value with */
  1321. /* fixed-array representation*/
  1322. output("%s = 0;\n", lenref);
  1323. }
  1324. else
  1325. if (info->Rules & eTypeRules_SinglyLinkedList)
  1326. {
  1327. /* use additional iterator for sequence of/set of value with */
  1328. /* singly-linked-list representation */
  1329. outputvar("P%s *f;\n", info->Identifier);
  1330. output("f = %s;\n", Reference(valref));
  1331. }
  1332. else
  1333. if (info->Rules & eTypeRules_DoublyLinkedList)
  1334. {
  1335. /* use additional iterator and iterator pointer for sequence of/ */
  1336. /* set of value with doubly-linked-list representation */
  1337. outputvar("P%s *f;\n", info->Identifier);
  1338. outputvar("%s b;\n", info->Identifier);
  1339. output("f = %s;\n", Reference(valref));
  1340. output("b = NULL;\n");
  1341. }
  1342. /* decode while not constructed is not empty */
  1343. output("while (ASN1BERDecNotEndOfContents(%s, di)) {\n", encref);
  1344. /* get next tag */
  1345. output("if (!ASN1BERDecPeekTag(%s, &t))\n", encref);
  1346. output("return 0;\n");
  1347. if (info->Rules & eTypeRules_PointerArrayMask)
  1348. {
  1349. if (info->Rules & eTypeRules_LengthPointer)
  1350. {
  1351. /* resize allocated array if it is too small */
  1352. output("if (%s >= n) {\n", lenref);
  1353. output("n = n ? (n << 1) : 16;\n");
  1354. output("if (!(%s = (%s *)ASN1DecRealloc(%s, %s, n * sizeof(%s))))\n",
  1355. valref, GetTypeName(ass, info->SubType), encref,
  1356. valref, Dereference(valref));
  1357. output("return 0;\n");
  1358. output("}\n");
  1359. }
  1360. /* get the name of the value */
  1361. sprintf(valbuf, "(%s)[%s]", valref, lenref);
  1362. }
  1363. else
  1364. if (info->Rules & eTypeRules_LinkedListMask)
  1365. {
  1366. /* allocate one element */
  1367. output("if (!(*f = (P%s)ASN1DecAlloc(%s, sizeof(**f))))\n",
  1368. info->Identifier, encref);
  1369. output("return 0;\n");
  1370. /* get the name of the value */
  1371. sprintf(valbuf, "(*f)->value");
  1372. }
  1373. /* decode the element */
  1374. GenBERFuncSimpleType(ass, &info->SubType->BERTypeInfo, valbuf,
  1375. eDecode, encref, NULL);
  1376. if (info->Rules &
  1377. (eTypeRules_LengthPointer | eTypeRules_FixedArray)) {
  1378. /* advance the length of the array contents */
  1379. output("(%s)++;\n", lenref);
  1380. } else if (info->Rules & eTypeRules_SinglyLinkedList) {
  1381. /* adjust the pointer for the next element */
  1382. output("f = &(*f)->next;\n");
  1383. } else if (info->Rules & eTypeRules_DoublyLinkedList) {
  1384. /* adjust the pointer for the next element and */
  1385. /* update the back pointer */
  1386. output("(*f)->prev = b;\n");
  1387. output("b = *f;\n");
  1388. output("f = &b->next;\n");
  1389. }
  1390. /* end of loop */
  1391. output("}\n");
  1392. if (info->Rules & eTypeRules_LengthPointer)
  1393. {
  1394. #if 0 // lonchanc: no need to shrink the memory thru realloc
  1395. // lonchanc: no need to allocate memory for eTypeRules_FixedArray
  1396. /* resize allocated array to real size */
  1397. output("if (n != %s) {\n", lenref);
  1398. output("if (!(%s = (%s *)ASN1DecRealloc(%s, %s, %s * sizeof(%s))))\n",
  1399. valref, GetTypeName(ass, info->SubType), encref,
  1400. valref, lenref, Dereference(valref));
  1401. output("return 0;\n");
  1402. output("}\n");
  1403. #endif // 0
  1404. }
  1405. else
  1406. if (info->Rules & eTypeRules_LinkedListMask)
  1407. {
  1408. /* terminate the list */
  1409. output("*f = NULL;\n");
  1410. }
  1411. /* decode end-of-contents */
  1412. output("if (!ASN1BERDecEndOfContents(%s, dd, di))\n", oldencref2);
  1413. output("return 0;\n");
  1414. break;
  1415. case eBERSTIData_ObjectIdentifier:
  1416. if (info->pPrivateDirectives->fOidArray || g_fOidArray)
  1417. {
  1418. /* decode an object identifier value */
  1419. output("if (!ASN1BERDecObjectIdentifier2(%s, %s, %s))\n",
  1420. encref, tagref, Reference(valref));
  1421. }
  1422. else
  1423. {
  1424. /* decode an object identifier value */
  1425. output("if (!ASN1BERDecObjectIdentifier(%s, %s, %s))\n",
  1426. encref, tagref, Reference(valref));
  1427. }
  1428. output("return 0;\n");
  1429. break;
  1430. case eBERSTIData_ObjectIdEncoded:
  1431. /* decode an encoded object identifier value */
  1432. output("if (!ASN1BERDecEoid(%s, %s, %s))\n",
  1433. encref, tagref, Reference(valref));
  1434. output("return 0;\n");
  1435. break;
  1436. case eBERSTIData_String:
  1437. /* decode a string value */
  1438. if (info->NOctets == 1) {
  1439. p = "Char";
  1440. } else if (info->NOctets == 2) {
  1441. p = "Char16";
  1442. } else if (info->NOctets == 4) {
  1443. p = "Char32";
  1444. } else
  1445. MyAbort();
  1446. output("if (!ASN1BERDec%sString(%s, %s, %s))\n",
  1447. p, encref, tagref, Reference(valref));
  1448. output("return 0;\n");
  1449. break;
  1450. case eBERSTIData_ZeroString:
  1451. /* decode a zero-termianted string value */
  1452. if (info->NOctets == 1) {
  1453. p = "Char";
  1454. } else if (info->NOctets == 2) {
  1455. p = "Char16";
  1456. } else if (info->NOctets == 4) {
  1457. p = "Char32";
  1458. } else
  1459. MyAbort();
  1460. output("if (!ASN1BERDecZero%sString(%s, %s, %s))\n",
  1461. p, encref, tagref, Reference(valref));
  1462. output("return 0;\n");
  1463. break;
  1464. case eBERSTIData_External:
  1465. /* decode an external value */
  1466. output("if (!ASN1BERDecExternal(%s, %s, %s))\n",
  1467. encref, tagref, Reference(valref));
  1468. output("return 0;\n");
  1469. break;
  1470. case eBERSTIData_EmbeddedPdv:
  1471. /* decode an embedded pdv value */
  1472. output("if (!ASN1BERDecEmbeddedPdv(%s, %s, %s))\n",
  1473. encref, tagref, Reference(valref));
  1474. output("return 0;\n");
  1475. break;
  1476. case eBERSTIData_MultibyteString:
  1477. /* decode a multibyte string value */
  1478. if (info->Rules & eTypeRules_LengthPointer)
  1479. {
  1480. output("if (!ASN1BERDecMultibyteString(%s, %s, %s))\n",
  1481. encref, tagref, Reference(valref));
  1482. }
  1483. else
  1484. {
  1485. output("if (!ASN1BERDecZeroMultibyteString(%s, %s, %s))\n",
  1486. encref, tagref, Reference(valref));
  1487. }
  1488. output("return 0;\n");
  1489. break;
  1490. case eBERSTIData_UnrestrictedString:
  1491. /* decode an character string value */
  1492. output("if (!ASN1BERDecCharacterString(%s, %s, %s))\n",
  1493. encref, tagref, Reference(valref));
  1494. output("return 0;\n");
  1495. break;
  1496. case eBERSTIData_GeneralizedTime:
  1497. /* decode a generalized time value */
  1498. output("if (!ASN1BERDecGeneralizedTime(%s, %s, %s))\n",
  1499. encref, tagref, Reference(valref));
  1500. output("return 0;\n");
  1501. break;
  1502. case eBERSTIData_UTCTime:
  1503. /* decode a utc time value */
  1504. output("if (!ASN1BERDecUTCTime(%s, %s, %s))\n",
  1505. encref, tagref, Reference(valref));
  1506. output("return 0;\n");
  1507. break;
  1508. case eBERSTIData_Reference:
  1509. /* call other encoding function for reference types */
  1510. output("if (!ASN1Dec_%s(%s, %s, %s))\n",
  1511. Identifier2C(info->SubIdentifier),
  1512. encref, tagref, Reference(valref));
  1513. output("return 0;\n");
  1514. break;
  1515. case eBERSTIData_Open:
  1516. /* decode an open type value */
  1517. output("if (!ASN1BERDecOpenType%s(%s, %s))\n",
  1518. info->pPrivateDirectives->fNoMemCopy ? "2" : "",
  1519. encref, Reference(valref));
  1520. output("return 0;\n");
  1521. break;
  1522. case eBERSTIData_Boolean:
  1523. if (g_fCaseBasedOptimizer)
  1524. {
  1525. output("if (!ASN1BERDecBool(%s, %s, %s))\n", encref, tagref, Reference(valref));
  1526. output("return 0;\n");
  1527. }
  1528. break;
  1529. }
  1530. /* check length/get eoc for explicit tags */
  1531. GenBERDecTagEnd(DECODER_NAME, STREAM_END_NAME, depth, oldencref);
  1532. }