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.

682 lines
20 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. #if defined(ENABLE_COMPARE) || defined(ENABLE_BER)
  5. /* compare two object identifiers; return 0 iff equal */
  6. int ASN1objectidentifier_cmp(ASN1objectidentifier_t *v1, ASN1objectidentifier_t *v2)
  7. {
  8. ASN1uint32_t l, l1, l2, i;
  9. ASN1objectidentifier_t p1 = *v1;
  10. ASN1objectidentifier_t p2 = *v2;
  11. l1 = GetObjectIdentifierCount(p1);
  12. l2 = GetObjectIdentifierCount(p2);
  13. l = (l1 > l2) ? l2 : l1; // min(l1,l2)
  14. for (i = 0; i < l; i++) {
  15. if (p1->value != p2->value)
  16. return p1->value - p2->value;
  17. p1 = p1->next;
  18. p2 = p2->next;
  19. }
  20. return l1 - l2;
  21. }
  22. int ASN1objectidentifier2_cmp(ASN1objectidentifier2_t *v1, ASN1objectidentifier2_t *v2)
  23. {
  24. ASN1uint16_t len, i;
  25. len = (v1->count > v2->count) ? v2->count : v1->count; // min(l1,l2)
  26. for (i = 0; i < len; i++)
  27. {
  28. if (v1->value[i] != v2->value[i])
  29. {
  30. return ((int) v1->value[i] - (int) v2->value[i]);
  31. }
  32. }
  33. return ((int) v1->count - (int) v2->count);
  34. }
  35. static const ASN1uint8_t c_aBitMask2[] = {
  36. 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe
  37. };
  38. /* compare two bit strings; return 0 iff equal */
  39. int ASN1bitstring_cmp(ASN1bitstring_t *v1, ASN1bitstring_t *v2, int ignorezero)
  40. {
  41. ASN1uint32_t l, l1, l2;
  42. ASN1octet_t o1, o2;
  43. int ret;
  44. l1 = v1->length;
  45. l2 = v2->length;
  46. l = l1;
  47. if (l > l2)
  48. l = l2;
  49. if (ignorezero) {
  50. if (l1 > l)
  51. ASN1PEREncRemoveZeroBits(&l1, v1->value, l);
  52. if (l2 > l)
  53. ASN1PEREncRemoveZeroBits(&l2, v2->value, l);
  54. }
  55. if (l > 7) {
  56. ret = memcmp(v1->value, v2->value, l / 8);
  57. if (ret)
  58. return ret;
  59. }
  60. if (l & 7) {
  61. o1 = v1->value[l / 8] & c_aBitMask2[l & 7];
  62. o2 = v2->value[l / 8] & c_aBitMask2[l & 7];
  63. ret = o1 - o2;
  64. if (ret)
  65. return ret;
  66. }
  67. return l1 - l2;
  68. }
  69. /* compare two octet strings; return 0 iff equal */
  70. int ASN1octetstring_cmp(ASN1octetstring_t *v1, ASN1octetstring_t *v2)
  71. {
  72. ASN1uint32_t l, l1, l2;
  73. int ret;
  74. l1 = v1->length;
  75. l2 = v2->length;
  76. l = l1;
  77. if (l > l2)
  78. l = l2;
  79. if (l) {
  80. ret = memcmp(v1->value, v2->value, l);
  81. if (ret)
  82. return ret;
  83. }
  84. return l1 - l2;
  85. }
  86. #ifdef ENABLE_EXTERNAL
  87. /* compare two external; return 0 iff equal */
  88. int ASN1external_cmp(ASN1external_t *v1, ASN1external_t *v2)
  89. {
  90. int ret;
  91. if ((ret = (v1->identification.o - v2->identification.o)))
  92. return ret;
  93. switch (v1->identification.o) {
  94. case ASN1external_identification_syntax_o:
  95. if ((ret = ASN1objectidentifier_cmp(&v1->identification.u.syntax,
  96. &v2->identification.u.syntax)))
  97. return ret;
  98. break;
  99. case ASN1external_identification_presentation_context_id_o:
  100. if ((ret = (v1->identification.u.presentation_context_id -
  101. v2->identification.u.presentation_context_id)))
  102. return ret;
  103. break;
  104. case ASN1external_identification_context_negotiation_o:
  105. if ((ret = (
  106. v1->identification.u.context_negotiation.presentation_context_id -
  107. v2->identification.u.context_negotiation.presentation_context_id)))
  108. return ret;
  109. if ((ret = ASN1objectidentifier_cmp(
  110. &v1->identification.u.context_negotiation.transfer_syntax,
  111. &v2->identification.u.context_negotiation.transfer_syntax)))
  112. return ret;
  113. break;
  114. }
  115. if (ASN1BITTEST(v1->o, ASN1external_data_value_descriptor_o)) {
  116. if (ASN1BITTEST(v2->o, ASN1external_data_value_descriptor_o)) {
  117. if ((ret = ASN1ztcharstring_cmp(
  118. v1->data_value_descriptor, v2->data_value_descriptor)))
  119. return ret;
  120. } else {
  121. return 1;
  122. }
  123. } else {
  124. return 1;
  125. }
  126. if ((ret = (v1->data_value.o - v2->data_value.o)))
  127. return ret;
  128. switch (v1->data_value.o) {
  129. case ASN1external_data_value_notation_o:
  130. if ((ret = ASN1open_cmp(&v1->data_value.u.notation,
  131. &v2->data_value.u.notation)))
  132. return ret;
  133. break;
  134. case ASN1external_data_value_encoded_o:
  135. if ((ret = ASN1bitstring_cmp(&v1->data_value.u.encoded,
  136. &v2->data_value.u.encoded, 0)))
  137. return ret;
  138. break;
  139. }
  140. return 0;
  141. }
  142. #endif // ENABLE_EXTERNAL
  143. #ifdef ENABLE_REAL
  144. /* compare two reals; return 0 iff equal */
  145. int ASN1real_cmp(ASN1real_t *v1, ASN1real_t *v2)
  146. {
  147. ASN1intx_t e, e1, e2, m1, m2, h;
  148. int ret = 0;
  149. ZeroMemory(&e1, sizeof(e1));
  150. ZeroMemory(&e2, sizeof(e2));
  151. ZeroMemory(&m1, sizeof(m1));
  152. ZeroMemory(&m2, sizeof(m2));
  153. if (v1->type == eReal_PlusInfinity || v2->type == eReal_MinusInfinity)
  154. return 1;
  155. if (v2->type == eReal_PlusInfinity || v1->type == eReal_MinusInfinity)
  156. return -1;
  157. if (v1->type != eReal_Normal || v2->type != eReal_Normal)
  158. return 0;
  159. switch (v1->base) {
  160. case 2:
  161. if (! ASN1intx_dup(&e1, &v1->exponent))
  162. {
  163. ret = -1;
  164. goto MyExit;
  165. }
  166. break;
  167. case 8:
  168. ASN1intx_muloctet(&e1, &v1->exponent, 3);
  169. break;
  170. case 16:
  171. ASN1intx_muloctet(&e1, &v1->exponent, 4);
  172. break;
  173. }
  174. switch (v2->base) {
  175. case 2:
  176. if (! ASN1intx_dup(&e2, &v2->exponent))
  177. {
  178. ret = 1;
  179. goto MyExit;
  180. }
  181. break;
  182. case 8:
  183. ASN1intx_muloctet(&e2, &v2->exponent, 3);
  184. break;
  185. case 16:
  186. ASN1intx_muloctet(&e2, &v2->exponent, 4);
  187. break;
  188. }
  189. if (! ASN1intx_dup(&m1, &v1->mantissa))
  190. {
  191. ret = -1;
  192. goto MyExit;
  193. }
  194. if (! ASN1intx_dup(&m2, &v2->mantissa))
  195. {
  196. ret = 1;
  197. goto MyExit;
  198. }
  199. ASN1intx_sub(&e, &e1, &e2);
  200. for (;;) {
  201. ret = ASN1intx_cmp(&e, &ASN1intx_0);
  202. if (!ret)
  203. break;
  204. if (ret > 0) {
  205. ASN1intx_muloctet(&h, &m1, 2);
  206. ASN1intx_free(&m1);
  207. m1 = h;
  208. ASN1intx_dec(&e);
  209. } else {
  210. ASN1intx_muloctet(&h, &m2, 2);
  211. ASN1intx_free(&m2);
  212. m2 = h;
  213. ASN1intx_inc(&e);
  214. }
  215. }
  216. // lonchanc: what happened to the memory allocated for e,
  217. // should we call ASN1intx_free(&e)?
  218. ret = ASN1intx_cmp(&m1, &m2);
  219. MyExit:
  220. ASN1intx_free(&m1);
  221. ASN1intx_free(&m2);
  222. ASN1intx_free(&e1);
  223. ASN1intx_free(&e2);
  224. return ret;
  225. }
  226. #endif // ENABLE_REAL
  227. /* compare two doubles; return 0 iff equal */
  228. int ASN1double_cmp(double d1, double d2)
  229. {
  230. return d1 < d2 ? -1 : d1 > d2 ? 1 : 0;
  231. }
  232. #ifdef ENABLE_EMBEDDED_PDV
  233. /* compare two embedded pdvs; return 0 iff equal */
  234. int ASN1embeddedpdv_cmp(ASN1embeddedpdv_t *v1, ASN1embeddedpdv_t *v2)
  235. {
  236. int ret;
  237. if ((ret = (v1->identification.o - v2->identification.o)))
  238. return ret;
  239. switch (v1->identification.o) {
  240. case ASN1embeddedpdv_identification_syntaxes_o:
  241. if ((ret = ASN1objectidentifier_cmp(
  242. &v1->identification.u.syntaxes.abstract,
  243. &v2->identification.u.syntaxes.abstract)))
  244. return ret;
  245. if ((ret = ASN1objectidentifier_cmp(
  246. &v1->identification.u.syntaxes.transfer,
  247. &v2->identification.u.syntaxes.transfer)))
  248. return ret;
  249. break;
  250. case ASN1embeddedpdv_identification_syntax_o:
  251. if ((ret = ASN1objectidentifier_cmp(&v1->identification.u.syntax,
  252. &v2->identification.u.syntax)))
  253. return ret;
  254. break;
  255. case ASN1embeddedpdv_identification_presentation_context_id_o:
  256. if ((ret = (v1->identification.u.presentation_context_id -
  257. v2->identification.u.presentation_context_id)))
  258. return ret;
  259. break;
  260. case ASN1embeddedpdv_identification_context_negotiation_o:
  261. if ((ret = (
  262. v1->identification.u.context_negotiation.presentation_context_id -
  263. v2->identification.u.context_negotiation.presentation_context_id)))
  264. return ret;
  265. if ((ret = ASN1objectidentifier_cmp(
  266. &v1->identification.u.context_negotiation.transfer_syntax,
  267. &v2->identification.u.context_negotiation.transfer_syntax)))
  268. return ret;
  269. break;
  270. case ASN1embeddedpdv_identification_transfer_syntax_o:
  271. if ((ret = ASN1objectidentifier_cmp(
  272. &v1->identification.u.transfer_syntax,
  273. &v2->identification.u.transfer_syntax)))
  274. return ret;
  275. break;
  276. case ASN1embeddedpdv_identification_fixed_o:
  277. break;
  278. }
  279. if ((ret = (v1->data_value.o - v2->data_value.o)))
  280. return ret;
  281. switch (v1->data_value.o) {
  282. case ASN1embeddedpdv_data_value_notation_o:
  283. if ((ret = ASN1open_cmp(&v1->data_value.u.notation,
  284. &v2->data_value.u.notation)))
  285. return ret;
  286. break;
  287. case ASN1embeddedpdv_data_value_encoded_o:
  288. if ((ret = ASN1bitstring_cmp(&v1->data_value.u.encoded,
  289. &v2->data_value.u.encoded, 0)))
  290. return ret;
  291. break;
  292. }
  293. return 0;
  294. }
  295. #endif // ENABLE_EMBEDDED_PDV
  296. /* compare two zero-terminated strings; return 0 iff equal */
  297. int ASN1ztcharstring_cmp(ASN1ztcharstring_t v1, ASN1ztcharstring_t v2)
  298. {
  299. if (v1 && v2)
  300. {
  301. return lstrcmpA(v1, v2);
  302. }
  303. return v1 ? 1 : -1;
  304. }
  305. /* compare two zero-terminated 16 bit strings; return 0 iff equal */
  306. int ASN1ztchar16string_cmp(ASN1ztchar16string_t v1, ASN1ztchar16string_t v2)
  307. {
  308. for (;;) {
  309. if (!*v1 || !*v2 || *v1 != *v2)
  310. return *v1 - *v2;
  311. v1++;
  312. v2++;
  313. }
  314. }
  315. /* compare two zero-terminated 32 bit strings; return 0 iff equal */
  316. int ASN1ztchar32string_cmp(ASN1ztchar32string_t v1, ASN1ztchar32string_t v2)
  317. {
  318. for (;;) {
  319. if (!*v1 || !*v2 || *v1 != *v2)
  320. return *v1 - *v2;
  321. v1++;
  322. v2++;
  323. }
  324. }
  325. /* compare two strings; return 0 iff equal */
  326. int ASN1charstring_cmp(ASN1charstring_t *v1, ASN1charstring_t *v2)
  327. {
  328. ASN1uint32_t i, l;
  329. l = v1->length;
  330. if (v2->length > l)
  331. l = v2->length;
  332. for (i = 0; i < l; i++) {
  333. if (v1->value[i] != v2->value[i])
  334. return v1->value[i] - v2->value[i];
  335. }
  336. return v1->length - v2->length;
  337. }
  338. /* compare two 16 bit strings; return 0 iff equal */
  339. int ASN1char16string_cmp(ASN1char16string_t *v1, ASN1char16string_t *v2)
  340. {
  341. ASN1uint32_t i, l;
  342. l = v1->length;
  343. if (v2->length > l)
  344. l = v2->length;
  345. for (i = 0; i < l; i++) {
  346. if (v1->value[i] != v2->value[i])
  347. return v1->value[i] - v2->value[i];
  348. }
  349. return v1->length - v2->length;
  350. }
  351. /* compare two 32 bit strings; return 0 iff equal */
  352. int ASN1char32string_cmp(ASN1char32string_t *v1, ASN1char32string_t *v2)
  353. {
  354. ASN1uint32_t i, l;
  355. l = v1->length;
  356. if (v2->length > l)
  357. l = v2->length;
  358. for (i = 0; i < l; i++) {
  359. if (v1->value[i] != v2->value[i])
  360. return v1->value[i] - v2->value[i];
  361. }
  362. return v1->length - v2->length;
  363. }
  364. #ifdef ENABLE_GENERALIZED_CHAR_STR
  365. /* compare two character strings; return 0 iff equal */
  366. int ASN1characterstring_cmp(ASN1characterstring_t *v1, ASN1characterstring_t *v2)
  367. {
  368. int ret;
  369. if ((ret = (v1->identification.o - v2->identification.o)))
  370. return ret;
  371. switch (v1->identification.o) {
  372. case ASN1characterstring_identification_syntaxes_o:
  373. if ((ret = ASN1objectidentifier_cmp(
  374. &v1->identification.u.syntaxes.abstract,
  375. &v2->identification.u.syntaxes.abstract)))
  376. return ret;
  377. if ((ret = ASN1objectidentifier_cmp(
  378. &v1->identification.u.syntaxes.transfer,
  379. &v2->identification.u.syntaxes.transfer)))
  380. return ret;
  381. break;
  382. case ASN1characterstring_identification_syntax_o:
  383. if ((ret = ASN1objectidentifier_cmp(&v1->identification.u.syntax,
  384. &v2->identification.u.syntax)))
  385. return ret;
  386. break;
  387. case ASN1characterstring_identification_presentation_context_id_o:
  388. if ((ret = (v1->identification.u.presentation_context_id -
  389. v2->identification.u.presentation_context_id)))
  390. return ret;
  391. break;
  392. case ASN1characterstring_identification_context_negotiation_o:
  393. if ((ret = (
  394. v1->identification.u.context_negotiation.presentation_context_id -
  395. v2->identification.u.context_negotiation.presentation_context_id)))
  396. return ret;
  397. if ((ret = ASN1objectidentifier_cmp(
  398. &v1->identification.u.context_negotiation.transfer_syntax,
  399. &v2->identification.u.context_negotiation.transfer_syntax)))
  400. return ret;
  401. break;
  402. case ASN1characterstring_identification_transfer_syntax_o:
  403. if ((ret = ASN1objectidentifier_cmp(
  404. &v1->identification.u.transfer_syntax,
  405. &v2->identification.u.transfer_syntax)))
  406. return ret;
  407. break;
  408. case ASN1characterstring_identification_fixed_o:
  409. break;
  410. }
  411. if ((ret = (v1->data_value.o - v2->data_value.o)))
  412. return ret;
  413. switch (v1->data_value.o) {
  414. case ASN1characterstring_data_value_notation_o:
  415. if ((ret = ASN1open_cmp(&v1->data_value.u.notation,
  416. &v2->data_value.u.notation)))
  417. return ret;
  418. break;
  419. case ASN1characterstring_data_value_encoded_o:
  420. if ((ret = ASN1octetstring_cmp(&v1->data_value.u.encoded,
  421. &v2->data_value.u.encoded)))
  422. return ret;
  423. break;
  424. }
  425. return 0;
  426. }
  427. #endif // ENABLE_GENERALIZED_CHAR_STR
  428. /* compare two utc times; return 0 iff equal */
  429. int ASN1utctime_cmp(ASN1utctime_t *v1, ASN1utctime_t *v2)
  430. {
  431. if (v1->universal != v2->universal || v1->diff != v2->diff)
  432. return 1;
  433. if (v1->year != v2->year)
  434. return v1->year - v2->year;
  435. if (v1->month != v2->month)
  436. return v1->month - v2->month;
  437. if (v1->day != v2->day)
  438. return v1->day - v2->day;
  439. if (v1->hour != v2->hour)
  440. return v1->hour - v2->hour;
  441. if (v1->minute != v2->minute)
  442. return v1->minute - v2->minute;
  443. return v1->second - v2->second;
  444. }
  445. /* compare two generalized times; return 0 iff equal */
  446. int ASN1generalizedtime_cmp(ASN1generalizedtime_t *v1, ASN1generalizedtime_t *v2)
  447. {
  448. if (v1->universal != v2->universal || v1->diff != v2->diff)
  449. return 1;
  450. if (v1->year != v2->year)
  451. return v1->year - v2->year;
  452. if (v1->month != v2->month)
  453. return v1->month - v2->month;
  454. if (v1->day != v2->day)
  455. return v1->day - v2->day;
  456. if (v1->hour != v2->hour)
  457. return v1->hour - v2->hour;
  458. if (v1->minute != v2->minute)
  459. return v1->minute - v2->minute;
  460. if (v1->second != v2->second)
  461. return v1->second - v2->second;
  462. return v1->millisecond - v2->millisecond;
  463. }
  464. /* compare two open type values; return 0 iff equal */
  465. int ASN1open_cmp(ASN1open_t *v1, ASN1open_t *v2)
  466. {
  467. ASN1octetstring_t ostr1, ostr2;
  468. ostr1.length = v1->length;
  469. ostr1.value = v1->encoded;
  470. ostr2.length = v2->length;
  471. ostr2.value = v2->encoded;
  472. return ASN1octetstring_cmp(&ostr1, &ostr2);
  473. }
  474. /* compare two sequence of values with length-pointer representation */
  475. /* return 0 iff equal */
  476. int ASN1sequenceoflengthpointer_cmp(ASN1uint32_t l1, void *v1, ASN1uint32_t l2, void *v2, ASN1uint32_t size, int (*cmpfn)(void *v1, void *v2))
  477. {
  478. int ret;
  479. ASN1octet_t *p1, *p2;
  480. if ((ret = (l1 - l2)))
  481. return ret;
  482. for (p1 = (ASN1octet_t *)v1, p2 = (ASN1octet_t *)v2; l1--;
  483. p1 += size, p2 += size) {
  484. if ((ret = cmpfn(p1, p2)))
  485. return ret;
  486. }
  487. return 0;
  488. }
  489. /* compare two sequence of values with singly-linked-list representation */
  490. /* return 0 iff equal */
  491. int ASN1sequenceofsinglylinkedlist_cmp(void *v1, void *v2, ASN1uint32_t off, int (*cmpfn)(void *, void *))
  492. {
  493. int ret;
  494. ASN1octet_t *p1, *p2;
  495. for (p1 = (ASN1octet_t *)v1, p2 = (ASN1octet_t *)v2; p1 && p2;
  496. p1 = *(ASN1octet_t **)p1, p2 = *(ASN1octet_t **)p2) {
  497. if ((ret = cmpfn(p1 + off, p2 + off)))
  498. return ret;
  499. }
  500. return 0;
  501. }
  502. /* compare two sequence of values with doubly-linked-list representation */
  503. /* return 0 iff equal */
  504. int ASN1sequenceofdoublylinkedlist_cmp(void *v1, void *v2, ASN1uint32_t off, int (*cmpfn)(void *, void *))
  505. {
  506. int ret;
  507. ASN1octet_t *p1, *p2;
  508. for (p1 = (ASN1octet_t *)v1, p2 = (ASN1octet_t *)v2; p1 && p2;
  509. p1 = *(ASN1octet_t **)p1, p2 = *(ASN1octet_t **)p2) {
  510. if ((ret = cmpfn(p1 + off, p2 + off)))
  511. return ret;
  512. }
  513. return 0;
  514. }
  515. /* compare two set of values with length-pointer representation */
  516. /* return 0 iff equal */
  517. int ASN1setoflengthpointer_cmp(ASN1uint32_t l1, void *v1, ASN1uint32_t l2, void *v2, ASN1uint32_t size, int (*cmpfn)(void *v1, void *v2))
  518. {
  519. int ret;
  520. ASN1octet_t *p1, *p2, *found, *f;
  521. ASN1uint32_t l;
  522. if ((ret = (l1 - l2)))
  523. return ret;
  524. if (!l1)
  525. return 0;
  526. found = (ASN1octet_t *)MemAlloc(l1, UNKNOWN_MODULE);
  527. if (found)
  528. {
  529. memset(found, 0, l1);
  530. for (p1 = (ASN1octet_t *)v1; l1--; p1 += size) {
  531. for (p2 = (ASN1octet_t *)v2, l = l2, f = found; l; p2 += size, f++, l--) {
  532. if (!*f && !cmpfn(p1, p2)) {
  533. *f = 1;
  534. break;
  535. }
  536. }
  537. if (!l) {
  538. MemFree(found);
  539. return 1;
  540. }
  541. }
  542. MemFree(found);
  543. }
  544. return 0;
  545. }
  546. /* compare two set of values with singly-linked-list representation */
  547. /* return 0 iff equal */
  548. int ASN1setofsinglylinkedlist_cmp(void *v1, void *v2, ASN1uint32_t off, int (*cmpfn)(void *, void *))
  549. {
  550. int ret;
  551. ASN1octet_t *p1, *p2, *found, *f;
  552. ASN1uint32_t l1, l2;
  553. for (p1 = (ASN1octet_t *)v1, l1 = 0; p1; p1 = *(ASN1octet_t **)p1)
  554. l1++;
  555. for (p2 = (ASN1octet_t *)v2, l2 = 0; p2; p2 = *(ASN1octet_t **)p2)
  556. l2++;
  557. if ((ret = (l1 - l2)))
  558. return ret;
  559. if (!l1)
  560. return 0;
  561. found = (ASN1octet_t *)MemAlloc(l1, UNKNOWN_MODULE);
  562. if (found)
  563. {
  564. memset(found, 0, l1);
  565. for (p1 = (ASN1octet_t *)v1; p1; p1 = *(ASN1octet_t **)p1) {
  566. for (p2 = (ASN1octet_t *)v2, f = found; p2; p2 = *(ASN1octet_t **)p2, f++) {
  567. if (!*f && !cmpfn(p1 + off, p2 + off)) {
  568. *f = 1;
  569. break;
  570. }
  571. }
  572. if (!p2) {
  573. MemFree(found);
  574. return 1;
  575. }
  576. }
  577. MemFree(found);
  578. }
  579. return 0;
  580. }
  581. /* compare two set of values with doubly-linked-list representation */
  582. /* return 0 iff equal */
  583. int ASN1setofdoublylinkedlist_cmp(void *v1, void *v2, ASN1uint32_t off, int (*cmpfn)(void *, void *))
  584. {
  585. int ret;
  586. ASN1octet_t *p1, *p2, *found, *f;
  587. ASN1uint32_t l1, l2;
  588. for (p1 = (ASN1octet_t *)v1, l1 = 0; p1; p1 = *(ASN1octet_t **)p1)
  589. l1++;
  590. for (p2 = (ASN1octet_t *)v2, l2 = 0; p2; p2 = *(ASN1octet_t **)p2)
  591. l2++;
  592. if ((ret = (l1 - l2)))
  593. return ret;
  594. if (!l1)
  595. return 0;
  596. found = (ASN1octet_t *)MemAlloc(l1, UNKNOWN_MODULE);
  597. if (found)
  598. {
  599. memset(found, 0, l1);
  600. for (p1 = (ASN1octet_t *)v1; p1; p1 = *(ASN1octet_t **)p1) {
  601. for (p2 = (ASN1octet_t *)v2, f = found; p2; p2 = *(ASN1octet_t **)p2, f++) {
  602. if (!*f && !cmpfn(p1 + off, p2 + off)) {
  603. *f = 1;
  604. break;
  605. }
  606. }
  607. if (!p2) {
  608. MemFree(found);
  609. return 1;
  610. }
  611. }
  612. MemFree(found);
  613. }
  614. return 0;
  615. }
  616. #endif // defined(ENABLE_COMPARE) || defined(ENABLE_BER)