Leaked source code of windows server 2003
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.

1751 lines
56 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. // debug purpose
  757. output("default:\n\t/* impossible */\n");
  758. output("ASN1EncSetError(%s, ASN1_ERR_CHOICE);\n", encref);
  759. output("return 0;\n");
  760. output("}\n");
  761. break;
  762. case eDecode:
  763. if (fContainOpenTypeComWithDefTags)
  764. {
  765. if (info->Flags & eTypeFlags_ExtensionMarker)
  766. {
  767. output("} else {\n");
  768. output("(%s)->choice = %d;\n", valref, ASN1_CHOICE_BASE + ncomponents); /* unknown extens.*/
  769. output("if (!ASN1BERDecSkip(%s))\n", encref);
  770. output("return 0;\n");
  771. output("}\n");
  772. output("break;\n");
  773. }
  774. }
  775. else
  776. {
  777. output("default:\n");
  778. if (info->Flags & eTypeFlags_ExtensionMarker) {
  779. output("(%s)->choice = %d;\n", valref, ASN1_CHOICE_BASE + ncomponents); /* unknown extens.*/
  780. output("if (!ASN1BERDecSkip(%s))\n", encref);
  781. output("return 0;\n");
  782. output("break;\n");
  783. } else {
  784. output("ASN1DecSetError(%s, ASN1_ERR_CORRUPT);\n", encref);
  785. output("return 0;\n");
  786. }
  787. }
  788. output("}\n");
  789. break;
  790. }
  791. /* generate end of contents */
  792. switch (et) {
  793. case eEncode:
  794. GenBEREncTagEnd(LEN_OFFSET_STR2, neoc, encref);
  795. break;
  796. case eDecode:
  797. GenBERDecTagEnd(DECODER_NAME2, STREAM_END_NAME2, depth, oldencref);
  798. }
  799. }
  800. /* generate function body for simple type */
  801. void
  802. GenBERFuncSimpleType(AssignmentList_t ass, BERTypeInfo_t *info, char *valref, TypeFunc_e et, char *encref, char *tagref)
  803. {
  804. switch (et) {
  805. case eStringTable:
  806. break;
  807. case eEncode:
  808. GenBEREncSimpleType(ass, info, valref, encref, tagref);
  809. break;
  810. case eDecode:
  811. GenBERDecSimpleType(ass, info, valref, encref, tagref);
  812. break;
  813. }
  814. }
  815. /* generate encoding statements for a simple value */
  816. void
  817. GenBEREncSimpleType(AssignmentList_t ass, BERTypeInfo_t *info, char *valref, char *encref, char *tagref)
  818. {
  819. char *lenref;
  820. char lenbuf[256], valbuf[256];
  821. BERTypeInfo_t inf;
  822. inf = *info;
  823. /* examine type for special handling */
  824. switch (inf.Data) {
  825. case eBERSTIData_BitString:
  826. case eBERSTIData_RZBBitString:
  827. case eBERSTIData_OctetString:
  828. case eBERSTIData_UTF8String:
  829. case eBERSTIData_String:
  830. /* length and value of bit string, octet string and string */
  831. if (*valref != '*')
  832. {
  833. sprintf(lenbuf, "(%s).length", valref);
  834. sprintf(valbuf, "(%s).value", valref);
  835. }
  836. else
  837. {
  838. sprintf(lenbuf, "(%s)->length", Reference(valref));
  839. sprintf(valbuf, "(%s)->value", Reference(valref));
  840. }
  841. lenref = lenbuf;
  842. valref = valbuf;
  843. /* check for remove-zero-bits bit string */
  844. if (inf.Data == eBERSTIData_RZBBitString) {
  845. outputvar("ASN1uint32_t r;\n");
  846. output("r = %s;\n", lenref);
  847. output("ASN1BEREncRemoveZeroBits(&r, %s);\n",
  848. valref);
  849. lenref = "r";
  850. }
  851. break;
  852. case eBERSTIData_SequenceOf:
  853. case eBERSTIData_SetOf:
  854. if (inf.Rules & eTypeRules_PointerArrayMask)
  855. {
  856. /* length and value of sequence of/set of value with */
  857. /* length-pointer representation */
  858. sprintf(lenbuf, "(%s)->count", Reference(valref));
  859. sprintf(valbuf, "(%s)->value", Reference(valref));
  860. lenref = lenbuf;
  861. valref = valbuf;
  862. }
  863. else
  864. if (inf.Rules & eTypeRules_LinkedListMask)
  865. {
  866. lenref = "t";
  867. }
  868. else
  869. {
  870. MyAbort();
  871. }
  872. break;
  873. case eBERSTIData_ZeroString:
  874. /* length of a zero-terminated string value */
  875. outputvar("ASN1uint32_t t;\n");
  876. output("t = lstrlenA(%s);\n", valref);
  877. lenref = "t";
  878. break;
  879. case eBERSTIData_Boolean:
  880. if (g_fCaseBasedOptimizer)
  881. {
  882. if (BerOptCase_IsBoolean(&inf))
  883. {
  884. break;
  885. }
  886. }
  887. /* value of a boolean value */
  888. sprintf(valbuf, "(%s) ? 255 : 0", valref);
  889. valref = valbuf;
  890. inf.Data = eBERSTIData_Unsigned;
  891. break;
  892. default:
  893. /* other values have no additional length */
  894. lenref = NULL;
  895. break;
  896. }
  897. /* generate the encoding of the value */
  898. GenBEREncGenericUnextended(ass, &inf, valref, lenref, encref, tagref);
  899. }
  900. /* generate encoding statements for a simple value (after some special */
  901. /* handling has been done) */
  902. void
  903. GenBEREncGenericUnextended(AssignmentList_t ass, BERTypeInfo_t *info, char *valref, char *lenref, char *encref, char *tagref)
  904. {
  905. uint32_t neoc;
  906. char *p;
  907. char valbuf[256];
  908. /* encode tags */
  909. neoc = GenBEREncTag(LEN_OFFSET_STR, ass, info, encref, &tagref);
  910. /* encode length and value */
  911. switch (info->Data) {
  912. case eBERSTIData_Null:
  913. /* encode null value */
  914. output("if (!ASN1BEREncNull(%s, %s))\n", encref, tagref);
  915. output("return 0;\n");
  916. break;
  917. case eBERSTIData_Unsigned:
  918. case eBERSTIData_Integer:
  919. /* encode integer value; check for intx_t representation */
  920. if (info->NOctets) {
  921. if (info->Data == eBERSTIData_Unsigned) {
  922. output("if (!ASN1BEREncU32(%s, %s, %s))\n",
  923. encref, tagref, valref);
  924. } else {
  925. output("if (!ASN1BEREncS32(%s, %s, %s))\n",
  926. encref, tagref, valref);
  927. }
  928. output("return 0;\n");
  929. } else {
  930. output("if (!ASN1BEREncSX(%s, %s, %s))\n",
  931. encref, tagref, Reference(valref));
  932. output("return 0;\n");
  933. }
  934. break;
  935. case eBERSTIData_Real:
  936. /* encode real value; check for real_t representation */
  937. if (info->NOctets)
  938. output("if (!ASN1BEREncDouble(%s, %s, %s))\n",
  939. encref, tagref, valref);
  940. else
  941. output("if (!ASN1BEREncReal(%s, %s, %s))\n",
  942. encref, tagref, Reference(valref));
  943. output("return 0;\n");
  944. break;
  945. case eBERSTIData_BitString:
  946. case eBERSTIData_RZBBitString:
  947. /* encode bit string value */
  948. output("if (!ASN1%cEREncBitString(%s, %s, %s, %s))\n",
  949. g_eSubEncodingRule, encref, tagref, lenref, valref);
  950. output("return 0;\n");
  951. break;
  952. case eBERSTIData_OctetString:
  953. /* encode octet string value */
  954. output("if (!ASN1%cEREncOctetString(%s, %s, %s, %s))\n",
  955. g_eSubEncodingRule, encref, tagref, lenref, valref);
  956. output("return 0;\n");
  957. break;
  958. case eBERSTIData_UTF8String:
  959. /* encode octet string value */
  960. output("if (!ASN1%cEREncUTF8String(%s, %s, %s, %s))\n",
  961. g_eSubEncodingRule, encref, tagref, lenref, valref);
  962. output("return 0;\n");
  963. break;
  964. case eBERSTIData_SetOf:
  965. /* encoding of a set of value */
  966. if (eSubEncoding_Canonical == g_eSubEncodingRule ||
  967. eSubEncoding_Distinguished == g_eSubEncodingRule)
  968. {
  969. /* encoding of a set of value for DER/CER */
  970. /* lists will require an additional iterator */
  971. if (info->Rules &
  972. (eTypeRules_SinglyLinkedList | eTypeRules_DoublyLinkedList))
  973. {
  974. outputvar("P%s f;\n", info->Identifier);
  975. }
  976. /* encode the tag and infinite-length first */
  977. outputvar("ASN1uint32_t %s;\n", LEN_OFFSET_STR);
  978. output("if (!ASN1BEREncExplicitTag(%s, %s, &%s))\n", encref, tagref, LEN_OFFSET_STR);
  979. output("return 0;\n");
  980. /* create the SetOf block */
  981. outputvar("void *pBlk;\n");
  982. output("if (!ASN1DEREncBeginBlk(%s, ASN1_DER_SET_OF_BLOCK, &pBlk))\n", encref);
  983. output("return 0;\n");
  984. /* encode all elements */
  985. /* get the name of the elements */
  986. /* advance the iterator for lists */
  987. if (info->Rules & eTypeRules_PointerArrayMask)
  988. {
  989. outputvar("ASN1uint32_t i;\n");
  990. output("for (i = 0; i < %s; i++) {\n", lenref);
  991. sprintf(valbuf, "(%s)[i]", valref);
  992. }
  993. else if (info->Rules & eTypeRules_LinkedListMask)
  994. {
  995. output("for (f = %s; f; f = f->next) {\n", valref);
  996. sprintf(valbuf, "f->value");
  997. }
  998. else
  999. {
  1000. MyAbort();
  1001. }
  1002. /* create the secondary encoder structure */
  1003. outputvar("ASN1encoding_t enc2;\n");
  1004. output("if (!ASN1DEREncNewBlkElement(pBlk, &enc2))\n");
  1005. output("return 0;\n");
  1006. /* encode the element */
  1007. GenBERFuncSimpleType(ass, &info->SubType->BERTypeInfo, valbuf,
  1008. eEncode, "enc2", NULL);
  1009. /* create the secondary encoder structure */
  1010. output("if (!ASN1DEREncFlushBlkElement(pBlk))\n");
  1011. output("return 0;\n");
  1012. /* end of loop */
  1013. output("}\n");
  1014. /* create the secondary encoder structure */
  1015. output("if (!ASN1DEREncEndBlk(pBlk))\n");
  1016. output("return 0;\n");
  1017. /* encode the end-of-contents octets */
  1018. output("if (!ASN1BEREncEndOfContents(%s, %s))\n", encref, LEN_OFFSET_STR);
  1019. output("return 0;\n");
  1020. break;
  1021. }
  1022. /*FALLTHROUGH*/
  1023. case eBERSTIData_SequenceOf:
  1024. /* encoding of a sequence of value */
  1025. /* lists will require an additional iterator */
  1026. if (info->Rules & eTypeRules_LinkedListMask)
  1027. {
  1028. outputvar("P%s f;\n", info->Identifier);
  1029. }
  1030. /* encode the tag and infinite-length first */
  1031. outputvar("ASN1uint32_t %s;\n", LEN_OFFSET_STR);
  1032. output("if (!ASN1BEREncExplicitTag(%s, %s, &%s))\n", encref, tagref, LEN_OFFSET_STR);
  1033. output("return 0;\n");
  1034. /* encode all elements */
  1035. /* get the name of the elements */
  1036. /* advance the iterator for lists */
  1037. if (info->Rules & eTypeRules_PointerArrayMask)
  1038. {
  1039. outputvar("ASN1uint32_t i;\n");
  1040. output("for (i = 0; i < %s; i++) {\n", lenref);
  1041. sprintf(valbuf, "(%s)[i]", valref);
  1042. }
  1043. else if (info->Rules & eTypeRules_LinkedListMask)
  1044. {
  1045. output("for (f = %s; f; f = f->next) {\n", valref);
  1046. sprintf(valbuf, "f->value");
  1047. }
  1048. else
  1049. {
  1050. MyAbort();
  1051. }
  1052. /* encode the element */
  1053. GenBERFuncSimpleType(ass, &info->SubType->BERTypeInfo, valbuf,
  1054. eEncode, encref, NULL);
  1055. /* end of loop */
  1056. output("}\n");
  1057. /* encode the end-of-contents octets */
  1058. output("if (!ASN1BEREncEndOfContents(%s, %s))\n", encref, LEN_OFFSET_STR);
  1059. output("return 0;\n");
  1060. break;
  1061. case eBERSTIData_ObjectIdentifier:
  1062. /* encode an object identifier value */
  1063. if (info->pPrivateDirectives->fOidArray || g_fOidArray)
  1064. {
  1065. output("if (!ASN1BEREncObjectIdentifier2(%s, %s, %s))\n",
  1066. encref, tagref, Reference(valref));
  1067. }
  1068. else
  1069. {
  1070. output("if (!ASN1BEREncObjectIdentifier(%s, %s, %s))\n",
  1071. encref, tagref, Reference(valref));
  1072. }
  1073. output("return 0;\n");
  1074. break;
  1075. case eBERSTIData_ObjectIdEncoded:
  1076. /* encode an encoded object identifier value */
  1077. output("if (!ASN1BEREncEoid(%s, %s, %s))\n",
  1078. encref, tagref, Reference(valref));
  1079. output("return 0;\n");
  1080. break;
  1081. case eBERSTIData_String:
  1082. case eBERSTIData_ZeroString:
  1083. /* encode a string value */
  1084. if (info->NOctets == 1) {
  1085. p = "Char";
  1086. } else if (info->NOctets == 2) {
  1087. p = "Char16";
  1088. } else if (info->NOctets == 4) {
  1089. p = "Char32";
  1090. } else
  1091. MyAbort();
  1092. output("if (!ASN1%cEREnc%sString(%s, %s, %s, %s))\n",
  1093. g_eSubEncodingRule, p, encref, tagref, lenref, valref);
  1094. output("return 0;\n");
  1095. break;
  1096. case eBERSTIData_External:
  1097. /* encode an external value */
  1098. output("if (!ASN1BEREncExternal(%s, %s, %s))\n",
  1099. encref, tagref, Reference(valref));
  1100. output("return 0;\n");
  1101. break;
  1102. case eBERSTIData_EmbeddedPdv:
  1103. /* encode an embedded pdv value */
  1104. output("if (!ASN1BEREncEmbeddedPdv(%s, %s, %s))\n",
  1105. encref, tagref, Reference(valref));
  1106. output("return 0;\n");
  1107. break;
  1108. case eBERSTIData_MultibyteString:
  1109. /* encode a multibyte string value */
  1110. if (info->Rules & eTypeRules_LengthPointer)
  1111. {
  1112. output("if (!ASN1%cEREncMultibyteString(%s, %s, %s))\n",
  1113. g_eSubEncodingRule, encref, tagref, Reference(valref));
  1114. }
  1115. else
  1116. {
  1117. output("if (!ASN1%cEREncZeroMultibyteString(%s, %s, %s))\n",
  1118. g_eSubEncodingRule, encref, tagref, valref);
  1119. }
  1120. output("return 0;\n");
  1121. break;
  1122. case eBERSTIData_UnrestrictedString:
  1123. /* encode an character string value */
  1124. output("if (!ASN1BEREncCharacterString(%s, %s, %s))\n",
  1125. encref, tagref, Reference(valref));
  1126. output("return 0;\n");
  1127. break;
  1128. case eBERSTIData_GeneralizedTime:
  1129. /* encode a generalized time value */
  1130. output("if (!ASN1%cEREncGeneralizedTime(%s, %s, %s))\n",
  1131. g_eSubEncodingRule, encref, tagref, Reference(valref));
  1132. output("return 0;\n");
  1133. break;
  1134. case eBERSTIData_UTCTime:
  1135. /* encode a utc time value */
  1136. output("if (!ASN1%cEREncUTCTime(%s, %s, %s))\n",
  1137. g_eSubEncodingRule, encref, tagref, Reference(valref));
  1138. output("return 0;\n");
  1139. break;
  1140. case eBERSTIData_Open:
  1141. /* encode an open type value */
  1142. output("if (!ASN1BEREncOpenType(%s, %s))\n",
  1143. encref, Reference(valref));
  1144. output("return 0;\n");
  1145. break;
  1146. case eBERSTIData_Reference:
  1147. /* call other encoding function for reference types */
  1148. output("if (!ASN1Enc_%s(%s, %s, %s))\n",
  1149. Identifier2C(info->SubIdentifier),
  1150. encref, tagref, Reference(valref));
  1151. output("return 0;\n");
  1152. break;
  1153. case eBERSTIData_Boolean:
  1154. if (g_fCaseBasedOptimizer)
  1155. {
  1156. output("if (!ASN1BEREncBool(%s, %s, %s))\n", encref, tagref, valref);
  1157. output("return 0;\n");
  1158. }
  1159. break;
  1160. }
  1161. /* encode the end of tag octets */
  1162. GenBEREncTagEnd(LEN_OFFSET_STR, neoc, encref);
  1163. }
  1164. /* generate decoding statements for a simple value */
  1165. void
  1166. GenBERDecSimpleType(AssignmentList_t ass, BERTypeInfo_t *info, char *valref, char *encref, char *tagref)
  1167. {
  1168. char valbuf[256], lenbuf[256];
  1169. char *lenref;
  1170. BERTypeInfo_t inf;
  1171. inf = *info;
  1172. /* examine type for special handling */
  1173. switch (inf.Data) {
  1174. case eBERSTIData_SequenceOf:
  1175. case eBERSTIData_SetOf:
  1176. if (inf.Rules & eTypeRules_PointerArrayMask)
  1177. {
  1178. /* length and value of sequence of/set of value with */
  1179. /* length-pointer representation */
  1180. sprintf(lenbuf, "(%s)->count", Reference(valref));
  1181. sprintf(valbuf, "(%s)->value", Reference(valref));
  1182. lenref = lenbuf;
  1183. valref = valbuf;
  1184. }
  1185. else
  1186. if (inf.Rules & eTypeRules_LinkedListMask)
  1187. {
  1188. /* use a loop for sequence of/set of value with */
  1189. /* list representation */
  1190. outputvar("P%s *f;\n", inf.Identifier);
  1191. lenref = NULL;
  1192. }
  1193. else
  1194. {
  1195. MyAbort();
  1196. }
  1197. break;
  1198. case eBERSTIData_Boolean:
  1199. if (g_fCaseBasedOptimizer)
  1200. {
  1201. if (BerOptCase_IsBoolean(&inf))
  1202. {
  1203. break;
  1204. }
  1205. }
  1206. /* boolean value */
  1207. inf.Data = eBERSTIData_Unsigned;
  1208. lenref = NULL;
  1209. break;
  1210. default:
  1211. /* other values have no additional length */
  1212. lenref = NULL;
  1213. break;
  1214. }
  1215. /* generate the decoding of the value */
  1216. GenBERDecGenericUnextended(ass, &inf, valref, lenref, encref, tagref);
  1217. }
  1218. /* generate decoding statements for a simple value (after some special */
  1219. /* handling has been done) */
  1220. void
  1221. GenBERDecGenericUnextended(AssignmentList_t ass, BERTypeInfo_t *info, char *valref, char *lenref, char *encref, char *tagref)
  1222. {
  1223. uint32_t depth;
  1224. char *p;
  1225. char *oldencref;
  1226. char *oldencref2;
  1227. char valbuf[256];
  1228. /* decode tags */
  1229. oldencref = encref;
  1230. depth = GenBERDecTag(DECODER_NAME, STREAM_END_NAME, ass, info, &encref, &tagref);
  1231. /* decode length and value */
  1232. switch (info->Data) {
  1233. case eBERSTIData_Null:
  1234. /* decode null value */
  1235. output("if (!ASN1BERDecNull(%s, %s))\n", encref, tagref);
  1236. output("return 0;\n");
  1237. break;
  1238. case eBERSTIData_Integer:
  1239. /* decode integer value; check for intx_t representation */
  1240. if (!info->NOctets) {
  1241. output("if (!ASN1BERDecSXVal(%s, %s, %s))\n",
  1242. encref, tagref, Reference(valref));
  1243. output("return 0;\n");
  1244. } else {
  1245. output("if (!ASN1BERDecS%dVal(%s, %s, %s))\n",
  1246. info->NOctets * 8, encref, tagref, Reference(valref));
  1247. output("return 0;\n");
  1248. }
  1249. break;
  1250. case eBERSTIData_Unsigned:
  1251. if (!info->NOctets) {
  1252. output("if (!ASN1BERDecSXVal(%s, %s, %s))\n",
  1253. encref, tagref, Reference(valref));
  1254. output("return 0;\n");
  1255. } else {
  1256. unsigned long cBits = info->NOctets * 8;
  1257. if (32 == cBits)
  1258. {
  1259. output("if (!ASN1BERDecU32Val(%s, %s, (ASN1uint32_t *) %s))\n",
  1260. encref, tagref, Reference(valref));
  1261. }
  1262. else
  1263. {
  1264. output("if (!ASN1BERDecU%uVal(%s, %s, %s))\n",
  1265. cBits, encref, tagref, Reference(valref));
  1266. }
  1267. output("return 0;\n");
  1268. }
  1269. break;
  1270. case eBERSTIData_Real:
  1271. /* decode real value; check for real_t representation */
  1272. if (info->NOctets)
  1273. output("if (!ASN1BERDecDouble(%s, %s, %s))\n",
  1274. encref, tagref, Reference(valref));
  1275. else
  1276. output("if (!ASN1BERDecReal(%s, %s, %s))\n",
  1277. encref, tagref, Reference(valref));
  1278. output("return 0;\n");
  1279. break;
  1280. case eBERSTIData_BitString:
  1281. case eBERSTIData_RZBBitString:
  1282. /* decode bit string value */
  1283. output("if (!ASN1BERDecBitString%s(%s, %s, %s))\n",
  1284. info->pPrivateDirectives->fNoMemCopy ? "2" : "",
  1285. encref, tagref, Reference(valref));
  1286. output("return 0;\n");
  1287. break;
  1288. case eBERSTIData_OctetString:
  1289. /* decode octet string value */
  1290. output("if (!ASN1BERDecOctetString%s(%s, %s, %s))\n",
  1291. info->pPrivateDirectives->fNoMemCopy ? "2" : "",
  1292. encref, tagref, Reference(valref));
  1293. output("return 0;\n");
  1294. break;
  1295. case eBERSTIData_UTF8String:
  1296. /* decode octet string value */
  1297. output("if (!ASN1BERDecUTF8String(%s, %s, %s))\n",
  1298. encref, tagref, Reference(valref));
  1299. output("return 0;\n");
  1300. break;
  1301. case eBERSTIData_SetOf:
  1302. case eBERSTIData_SequenceOf:
  1303. /* encoding of a set of/sequence of value */
  1304. outputvar("ASN1decoding_t dd;\n");
  1305. outputvar("ASN1octet_t *di;\n");
  1306. /* decode the tag and length first */
  1307. output("if (!ASN1BERDecExplicitTag(%s, %s, &dd, &di))\n",
  1308. encref, tagref);
  1309. output("return 0;\n");
  1310. oldencref2 = encref;
  1311. encref = "dd";
  1312. outputvar("ASN1uint32_t t;\n");
  1313. if (info->Rules & eTypeRules_LengthPointer)
  1314. {
  1315. /* get length and value of sequence of/set of value with */
  1316. /* length-pointer representation */
  1317. outputvar("ASN1uint32_t n;\n");
  1318. output("%s = n = 0;\n", lenref);
  1319. output("%s = NULL;\n", valref);
  1320. }
  1321. else
  1322. if (info->Rules & eTypeRules_FixedArray)
  1323. {
  1324. /* get length and value of sequence of/set of value with */
  1325. /* fixed-array representation*/
  1326. output("%s = 0;\n", lenref);
  1327. }
  1328. else
  1329. if (info->Rules & eTypeRules_SinglyLinkedList)
  1330. {
  1331. /* use additional iterator for sequence of/set of value with */
  1332. /* singly-linked-list representation */
  1333. outputvar("P%s *f;\n", info->Identifier);
  1334. output("f = %s;\n", Reference(valref));
  1335. }
  1336. else
  1337. if (info->Rules & eTypeRules_DoublyLinkedList)
  1338. {
  1339. /* use additional iterator and iterator pointer for sequence of/ */
  1340. /* set of value with doubly-linked-list representation */
  1341. outputvar("P%s *f;\n", info->Identifier);
  1342. outputvar("%s b;\n", info->Identifier);
  1343. output("f = %s;\n", Reference(valref));
  1344. output("b = NULL;\n");
  1345. }
  1346. /* decode while not constructed is not empty */
  1347. output("while (ASN1BERDecNotEndOfContents(%s, di)) {\n", encref);
  1348. /* get next tag */
  1349. output("if (!ASN1BERDecPeekTag(%s, &t))\n", encref);
  1350. output("return 0;\n");
  1351. if (info->Rules & eTypeRules_PointerArrayMask)
  1352. {
  1353. if (info->Rules & eTypeRules_LengthPointer)
  1354. {
  1355. /* resize allocated array if it is too small */
  1356. output("if (%s >= n) {\n", lenref);
  1357. output("void *pvASN1DecRealloc;\n");
  1358. output("n = n ? (n << 1) : 16;\n");
  1359. output("if (!(pvASN1DecRealloc = ASN1DecRealloc(%s, %s, n * sizeof(%s))))\n",
  1360. encref,
  1361. valref, Dereference(valref));
  1362. output("return 0;\n");
  1363. output("%s = (%s *) pvASN1DecRealloc;\n",
  1364. valref, GetTypeName(ass, info->SubType));
  1365. output("}\n");
  1366. }
  1367. /* get the name of the value */
  1368. sprintf(valbuf, "(%s)[%s]", valref, lenref);
  1369. }
  1370. else
  1371. if (info->Rules & eTypeRules_LinkedListMask)
  1372. {
  1373. /* allocate one element */
  1374. output("if (!(*f = (P%s)ASN1DecAlloc(%s, sizeof(**f))))\n",
  1375. info->Identifier, encref);
  1376. output("return 0;\n");
  1377. /* get the name of the value */
  1378. sprintf(valbuf, "(*f)->value");
  1379. }
  1380. /* decode the element */
  1381. GenBERFuncSimpleType(ass, &info->SubType->BERTypeInfo, valbuf,
  1382. eDecode, encref, NULL);
  1383. if (info->Rules &
  1384. (eTypeRules_LengthPointer | eTypeRules_FixedArray)) {
  1385. /* advance the length of the array contents */
  1386. output("(%s)++;\n", lenref);
  1387. } else if (info->Rules & eTypeRules_SinglyLinkedList) {
  1388. /* adjust the pointer for the next element */
  1389. output("f = &(*f)->next;\n");
  1390. } else if (info->Rules & eTypeRules_DoublyLinkedList) {
  1391. /* adjust the pointer for the next element and */
  1392. /* update the back pointer */
  1393. output("(*f)->prev = b;\n");
  1394. output("b = *f;\n");
  1395. output("f = &b->next;\n");
  1396. }
  1397. /* end of loop */
  1398. output("}\n");
  1399. if (info->Rules & eTypeRules_LengthPointer)
  1400. {
  1401. #if 0 // lonchanc: no need to shrink the memory thru realloc
  1402. // lonchanc: no need to allocate memory for eTypeRules_FixedArray
  1403. /* resize allocated array to real size */
  1404. output("if (n != %s) {\n", lenref);
  1405. output("if (!(%s = (%s *)ASN1DecRealloc(%s, %s, %s * sizeof(%s))))\n",
  1406. valref, GetTypeName(ass, info->SubType), encref,
  1407. valref, lenref, Dereference(valref));
  1408. output("return 0;\n");
  1409. output("}\n");
  1410. #endif // 0
  1411. }
  1412. else
  1413. if (info->Rules & eTypeRules_LinkedListMask)
  1414. {
  1415. /* terminate the list */
  1416. output("*f = NULL;\n");
  1417. }
  1418. /* decode end-of-contents */
  1419. output("if (!ASN1BERDecEndOfContents(%s, dd, di))\n", oldencref2);
  1420. output("return 0;\n");
  1421. break;
  1422. case eBERSTIData_ObjectIdentifier:
  1423. if (info->pPrivateDirectives->fOidArray || g_fOidArray)
  1424. {
  1425. /* decode an object identifier value */
  1426. output("if (!ASN1BERDecObjectIdentifier2(%s, %s, %s))\n",
  1427. encref, tagref, Reference(valref));
  1428. }
  1429. else
  1430. {
  1431. /* decode an object identifier value */
  1432. output("if (!ASN1BERDecObjectIdentifier(%s, %s, %s))\n",
  1433. encref, tagref, Reference(valref));
  1434. }
  1435. output("return 0;\n");
  1436. break;
  1437. case eBERSTIData_ObjectIdEncoded:
  1438. /* decode an encoded object identifier value */
  1439. output("if (!ASN1BERDecEoid(%s, %s, %s))\n",
  1440. encref, tagref, Reference(valref));
  1441. output("return 0;\n");
  1442. break;
  1443. case eBERSTIData_String:
  1444. /* decode a string value */
  1445. if (info->NOctets == 1) {
  1446. p = "Char";
  1447. } else if (info->NOctets == 2) {
  1448. p = "Char16";
  1449. } else if (info->NOctets == 4) {
  1450. p = "Char32";
  1451. } else
  1452. MyAbort();
  1453. output("if (!ASN1BERDec%sString(%s, %s, %s))\n",
  1454. p, encref, tagref, Reference(valref));
  1455. output("return 0;\n");
  1456. break;
  1457. case eBERSTIData_ZeroString:
  1458. /* decode a zero-termianted string value */
  1459. if (info->NOctets == 1) {
  1460. p = "Char";
  1461. } else if (info->NOctets == 2) {
  1462. p = "Char16";
  1463. } else if (info->NOctets == 4) {
  1464. p = "Char32";
  1465. } else
  1466. MyAbort();
  1467. output("if (!ASN1BERDecZero%sString(%s, %s, %s))\n",
  1468. p, encref, tagref, Reference(valref));
  1469. output("return 0;\n");
  1470. break;
  1471. case eBERSTIData_External:
  1472. /* decode an external value */
  1473. output("if (!ASN1BERDecExternal(%s, %s, %s))\n",
  1474. encref, tagref, Reference(valref));
  1475. output("return 0;\n");
  1476. break;
  1477. case eBERSTIData_EmbeddedPdv:
  1478. /* decode an embedded pdv value */
  1479. output("if (!ASN1BERDecEmbeddedPdv(%s, %s, %s))\n",
  1480. encref, tagref, Reference(valref));
  1481. output("return 0;\n");
  1482. break;
  1483. case eBERSTIData_MultibyteString:
  1484. /* decode a multibyte string value */
  1485. if (info->Rules & eTypeRules_LengthPointer)
  1486. {
  1487. output("if (!ASN1BERDecMultibyteString(%s, %s, %s))\n",
  1488. encref, tagref, Reference(valref));
  1489. }
  1490. else
  1491. {
  1492. output("if (!ASN1BERDecZeroMultibyteString(%s, %s, %s))\n",
  1493. encref, tagref, Reference(valref));
  1494. }
  1495. output("return 0;\n");
  1496. break;
  1497. case eBERSTIData_UnrestrictedString:
  1498. /* decode an character string value */
  1499. output("if (!ASN1BERDecCharacterString(%s, %s, %s))\n",
  1500. encref, tagref, Reference(valref));
  1501. output("return 0;\n");
  1502. break;
  1503. case eBERSTIData_GeneralizedTime:
  1504. /* decode a generalized time value */
  1505. output("if (!ASN1BERDecGeneralizedTime(%s, %s, %s))\n",
  1506. encref, tagref, Reference(valref));
  1507. output("return 0;\n");
  1508. break;
  1509. case eBERSTIData_UTCTime:
  1510. /* decode a utc time value */
  1511. output("if (!ASN1BERDecUTCTime(%s, %s, %s))\n",
  1512. encref, tagref, Reference(valref));
  1513. output("return 0;\n");
  1514. break;
  1515. case eBERSTIData_Reference:
  1516. /* call other encoding function for reference types */
  1517. output("if (!ASN1Dec_%s(%s, %s, %s))\n",
  1518. Identifier2C(info->SubIdentifier),
  1519. encref, tagref, Reference(valref));
  1520. output("return 0;\n");
  1521. break;
  1522. case eBERSTIData_Open:
  1523. /* decode an open type value */
  1524. output("if (!ASN1BERDecOpenType%s(%s, %s))\n",
  1525. info->pPrivateDirectives->fNoMemCopy ? "2" : "",
  1526. encref, Reference(valref));
  1527. output("return 0;\n");
  1528. break;
  1529. case eBERSTIData_Boolean:
  1530. if (g_fCaseBasedOptimizer)
  1531. {
  1532. output("if (!ASN1BERDecBool(%s, %s, %s))\n", encref, tagref, Reference(valref));
  1533. output("return 0;\n");
  1534. }
  1535. break;
  1536. }
  1537. /* check length/get eoc for explicit tags */
  1538. GenBERDecTagEnd(DECODER_NAME, STREAM_END_NAME, depth, oldencref);
  1539. }