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.

346 lines
12 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 "cintern.h"
  5. /* external use only, allocate memory for decoding */
  6. LPVOID ASN1DecAlloc(ASN1decoding_t dec, ASN1uint32_t size)
  7. {
  8. return DecMemAlloc(dec, size);
  9. }
  10. /* external use only, reallocate memory for decoding */
  11. LPVOID ASN1DecRealloc(ASN1decoding_t dec, LPVOID ptr, ASN1uint32_t size)
  12. {
  13. return DecMemReAlloc(dec, ptr, size);
  14. }
  15. /* external use only, free a memory block */
  16. void ASN1Free(LPVOID ptr)
  17. {
  18. MemFree(ptr);
  19. }
  20. // lonchanc: we need to re-visit this approach of aborting a decoding
  21. /* abort decoding, free any memory allocated for decoding */
  22. void ASN1DecAbort(ASN1decoding_t dec)
  23. {
  24. ASN1INTERNdecoding_t d = ((ASN1INTERNdecoding_t)dec)->parent;
  25. #ifdef ENABLE_EXTRA_INFO
  26. /* clear the lists */
  27. d->memlength = d->epilength = d->csilength = 0;
  28. d->memsize = d->episize = d->csisize = 0;
  29. MemFree(d->mem);
  30. MemFree(d->epi);
  31. MemFree(d->csi);
  32. d->mem = NULL;
  33. d->epi = NULL;
  34. d->csi = NULL;
  35. #endif // ENABLE_EXTRA_INFO
  36. }
  37. // lonchanc: we need to re-visit this approach of aborting a decoding
  38. /* finish decoding */
  39. void ASN1DecDone(ASN1decoding_t dec)
  40. {
  41. ASN1INTERNdecoding_t d = ((ASN1INTERNdecoding_t)dec)->parent;
  42. #ifdef ENABLE_EXTRA_INFO
  43. /* clear the lists */
  44. d->memlength = d->epilength = d->csilength = 0;
  45. d->memsize = d->episize = d->csisize = 0;
  46. MemFree(d->mem);
  47. MemFree(d->epi);
  48. MemFree(d->csi);
  49. d->mem = NULL;
  50. d->epi = NULL;
  51. d->csi = NULL;
  52. #endif // ENABLE_EXTRA_INFO
  53. }
  54. // lonchanc: we need to re-visit this approach of aborting a decoding
  55. /* abort encoding, free any memory allocated for encoding */
  56. void ASN1EncAbort(ASN1encoding_t enc)
  57. {
  58. ASN1INTERNencoding_t e = ((ASN1INTERNencoding_t)enc)->parent;
  59. #ifdef ENABLE_EXTRA_INFO
  60. /* clear the lists */
  61. e->memlength = e->epilength = e->csilength = 0;
  62. e->memsize = e->episize = e->csisize = 0;
  63. MemFree(e->mem);
  64. MemFree(e->epi);
  65. MemFree(e->csi);
  66. e->mem = NULL;
  67. e->epi = NULL;
  68. e->csi = NULL;
  69. #endif // ENABLE_EXTRA_INFO
  70. }
  71. // lonchanc: we need to re-visit this approach of aborting a decoding
  72. /* finish encoding */
  73. void ASN1EncDone(ASN1encoding_t enc)
  74. {
  75. ASN1INTERNencoding_t e = ((ASN1INTERNencoding_t)enc)->parent;
  76. #ifdef ENABLE_EXTRA_INFO
  77. /* clear the lists */
  78. e->memlength = e->epilength = e->csilength = 0;
  79. e->memsize = e->episize = e->csisize = 0;
  80. MemFree(e->mem);
  81. MemFree(e->epi);
  82. MemFree(e->csi);
  83. e->mem = NULL;
  84. e->epi = NULL;
  85. e->csi = NULL;
  86. #endif // ENABLE_EXTRA_INFO
  87. }
  88. /* search the identification of an embedded pdv */
  89. #ifdef ENABLE_EMBEDDED_PDV
  90. int ASN1EncSearchEmbeddedPdvIdentification(ASN1INTERNencoding_t e, ASN1embeddedpdv_identification_t *identification, ASN1uint32_t *index, ASN1uint32_t *flag)
  91. {
  92. ASN1embeddedpdv_identification_t **id;
  93. /* search identification in indentification list */
  94. /* if found then reset flag (to indicate EP-B encoding) and return */
  95. for (*index = 0, id = e->epi; *index < e->epilength; (*index)++, id++) {
  96. if ((*id)->o == identification->o) {
  97. switch ((*id)->o) {
  98. case ASN1embeddedpdv_identification_syntaxes_o:
  99. if (!ASN1objectidentifier_cmp(&(*id)->u.syntaxes.abstract,
  100. &identification->u.syntaxes.abstract) &&
  101. !ASN1objectidentifier_cmp(&(*id)->u.syntaxes.transfer,
  102. &identification->u.syntaxes.transfer)) {
  103. *flag = 0;
  104. return 1;
  105. }
  106. break;
  107. case ASN1embeddedpdv_identification_syntax_o:
  108. if (!ASN1objectidentifier_cmp(&(*id)->u.syntax,
  109. &identification->u.syntax)) {
  110. *flag = 0;
  111. return 1;
  112. }
  113. break;
  114. case ASN1embeddedpdv_identification_presentation_context_id_o:
  115. if ((*id)->u.presentation_context_id ==
  116. identification->u.presentation_context_id) {
  117. *flag = 0;
  118. return 1;
  119. }
  120. break;
  121. case ASN1embeddedpdv_identification_context_negotiation_o:
  122. if ((*id)->u.context_negotiation.presentation_context_id ==
  123. identification->u.context_negotiation.
  124. presentation_context_id &&
  125. !ASN1objectidentifier_cmp(
  126. &(*id)->u.context_negotiation.transfer_syntax,
  127. &identification->u.context_negotiation.transfer_syntax)) {
  128. *flag = 0;
  129. return 1;
  130. }
  131. break;
  132. case ASN1embeddedpdv_identification_transfer_syntax_o:
  133. if (!ASN1objectidentifier_cmp(&(*id)->u.transfer_syntax,
  134. &identification->u.transfer_syntax)) {
  135. *flag = 0;
  136. return 1;
  137. }
  138. break;
  139. case ASN1embeddedpdv_identification_fixed_o:
  140. *flag = 0;
  141. return 1;
  142. default:
  143. e->parent->info.err = ASN1_ERR_CORRUPT;
  144. return 0;
  145. }
  146. }
  147. }
  148. /* identification not found */
  149. /* add it into indentification array */
  150. if (e->epilength >= e->episize) {
  151. e->episize = e->episize ? 4 * e->episize : 16;
  152. e->epi = (ASN1embeddedpdv_identification_t **)MemReAlloc(e->epi,
  153. e->episize * sizeof(ASN1embeddedpdv_identification_t *), _ModName((ASN1encoding_t) e));
  154. if (!e->epi)
  155. {
  156. ASN1EncSetError((ASN1encoding_t) e, ASN1_ERR_MEMORY);
  157. return 0;
  158. }
  159. }
  160. e->epi[e->epilength++] = identification;
  161. /* return flag for EP-A encoding */
  162. *flag = 1;
  163. return 1;
  164. }
  165. #endif // ENABLE_EMBEDDED_PDV
  166. /* search the identification of an character string */
  167. #ifdef ENABLE_GENERALIZED_CHAR_STR
  168. int ASN1EncSearchCharacterStringIdentification(ASN1INTERNencoding_t e, ASN1characterstring_identification_t *identification, ASN1uint32_t *index, ASN1uint32_t *flag)
  169. {
  170. ASN1characterstring_identification_t **id;
  171. /* search identification in indentification list */
  172. /* if found then reset flag (to indicate CS-B encoding) and return */
  173. for (*index = 0, id = e->csi; *index < e->csilength; (*index)++, id++) {
  174. if ((*id)->o == identification->o) {
  175. switch ((*id)->o) {
  176. case ASN1characterstring_identification_syntaxes_o:
  177. if (!ASN1objectidentifier_cmp(&(*id)->u.syntaxes.abstract,
  178. &identification->u.syntaxes.abstract) &&
  179. !ASN1objectidentifier_cmp(&(*id)->u.syntaxes.transfer,
  180. &identification->u.syntaxes.transfer)) {
  181. *flag = 0;
  182. return 1;
  183. }
  184. break;
  185. case ASN1characterstring_identification_syntax_o:
  186. if (!ASN1objectidentifier_cmp(&(*id)->u.syntax,
  187. &identification->u.syntax)) {
  188. *flag = 0;
  189. return 1;
  190. }
  191. break;
  192. case ASN1characterstring_identification_presentation_context_id_o:
  193. if ((*id)->u.presentation_context_id ==
  194. identification->u.presentation_context_id) {
  195. *flag = 0;
  196. return 1;
  197. }
  198. break;
  199. case ASN1characterstring_identification_context_negotiation_o:
  200. if ((*id)->u.context_negotiation.presentation_context_id ==
  201. identification->u.context_negotiation.
  202. presentation_context_id &&
  203. !ASN1objectidentifier_cmp(
  204. &(*id)->u.context_negotiation.transfer_syntax,
  205. &identification->u.context_negotiation.transfer_syntax)) {
  206. *flag = 0;
  207. return 1;
  208. }
  209. break;
  210. case ASN1characterstring_identification_transfer_syntax_o:
  211. if (!ASN1objectidentifier_cmp(&(*id)->u.transfer_syntax,
  212. &identification->u.transfer_syntax)) {
  213. *flag = 0;
  214. return 1;
  215. }
  216. break;
  217. case ASN1characterstring_identification_fixed_o:
  218. *flag = 0;
  219. return 1;
  220. default:
  221. e->parent->info.err = ASN1_ERR_CORRUPT;
  222. return 0;
  223. }
  224. }
  225. }
  226. /* identification not found */
  227. /* add it into indentification array */
  228. if (e->csilength >= e->csisize) {
  229. e->csisize = e->csisize ? 4 * e->csisize : 16;
  230. e->csi = (ASN1characterstring_identification_t **)MemReAlloc(e->csi,
  231. e->csisize * sizeof(ASN1characterstring_identification_t *), _ModName((ASN1encoding_t) e));
  232. if (!e->csi)
  233. {
  234. ASN1EncSetError((ASN1encoding_t) e, ASN1_ERR_MEMORY);
  235. return 0;
  236. }
  237. }
  238. e->csi[e->csilength++] = identification;
  239. /* return flag for CS-A encoding */
  240. *flag = 1;
  241. return 1;
  242. }
  243. #endif // ENABLE_GENERALIZED_CHAR_STR
  244. /* allocate and copy an object identifier */
  245. #if defined(ENABLE_GENERALIZED_CHAR_STR) || defined(ENABLE_EMBEDDED_PDV)
  246. int ASN1DecDupObjectIdentifier(ASN1decoding_t dec, ASN1objectidentifier_t *dst, ASN1objectidentifier_t *src)
  247. {
  248. ASN1INTERNdecoding_t d = ((ASN1INTERNdecoding_t)dec)->parent;
  249. ASN1uint32_t l = GetObjectIdentifierCount(*src);
  250. *dst = DecAllocObjectIdentifier(dec, l);
  251. if (! *dst)
  252. {
  253. ASN1DecSetError((ASN1decoding_t) d, ASN1_ERR_MEMORY);
  254. return 0;
  255. }
  256. CopyObjectIdentifier(*dst, *src);
  257. return 1;
  258. }
  259. #endif // defined(ENABLE_GENERALIZED_CHAR_STR) || defined(ENABLE_EMBEDDED_PDV)
  260. /* add an embedded pdv identification to the list of identifications */
  261. #ifdef ENABLE_EMBEDDED_PDV
  262. int ASN1DecAddEmbeddedPdvIdentification(ASN1INTERNdecoding_t d, ASN1embeddedpdv_identification_t *identification)
  263. {
  264. if (d->epilength >= d->episize) {
  265. d->episize = d->episize ? 4 * d->episize : 16;
  266. d->epi = (ASN1embeddedpdv_identification_t **)MemReAlloc(d->epi,
  267. d->episize * sizeof(ASN1embeddedpdv_identification_t *), _ModName((ASN1decoding_t) d));
  268. if (!d->epi)
  269. {
  270. ASN1DecSetError((ASN1decoding_t) d, ASN1_ERR_MEMORY);
  271. return 0;
  272. }
  273. }
  274. d->epi[d->epilength++] = identification;
  275. return 1;
  276. }
  277. #endif // ENABLE_EMBEDDED_PDV
  278. /* get an embedded pdv identification from the list of identifications */
  279. #ifdef ENABLE_EMBEDDED_PDV
  280. ASN1embeddedpdv_identification_t *ASN1DecGetEmbeddedPdvIdentification(ASN1INTERNdecoding_t d, ASN1uint32_t index)
  281. {
  282. if (index >= d->epilength)
  283. {
  284. ASN1DecSetError((ASN1decoding_t) d, ASN1_ERR_CORRUPT);
  285. return NULL;
  286. }
  287. return d->epi[index];
  288. }
  289. #endif // ENABLE_EMBEDDED_PDV
  290. /* add a character string identification to the list of identifications */
  291. #ifdef ENABLE_GENERALIZED_CHAR_STR
  292. int ASN1DecAddCharacterStringIdentification(ASN1INTERNdecoding_t d, ASN1characterstring_identification_t *identification)
  293. {
  294. if (d->csilength >= d->csisize) {
  295. d->csisize = d->csisize ? 4 * d->csisize : 16;
  296. d->csi = (ASN1characterstring_identification_t **)MemReAlloc(d->csi,
  297. d->csisize * sizeof(ASN1characterstring_identification_t *), _ModName((ASN1decoding_t) d));
  298. if (!d->csi)
  299. {
  300. ASN1DecSetError((ASN1decoding_t) d, ASN1_ERR_MEMORY);
  301. return 0;
  302. }
  303. }
  304. d->csi[d->csilength++] = identification;
  305. return 1;
  306. }
  307. #endif // ENABLE_GENERALIZED_CHAR_STR
  308. /* get a character string identification from the list of identifications */
  309. #ifdef ENABLE_GENERALIZED_CHAR_STR
  310. ASN1characterstring_identification_t *ASN1DecGetCharacterStringIdentification(ASN1INTERNdecoding_t d, ASN1uint32_t index)
  311. {
  312. if (index >= d->csilength)
  313. {
  314. ASN1DecSetError((ASN1decoding_t) d, ASN1_ERR_CORRUPT);
  315. return NULL;
  316. }
  317. return d->csi[index];
  318. }
  319. #endif // ENABLE_GENERALIZED_CHAR_STR