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.

5889 lines
188 KiB

  1. /*******************************************************************************
  2. * Copyright (c) 1998 Gemplus Development
  3. *
  4. * Name : COMPCERT.C
  5. *
  6. * Description : Programme de compression de certificat X.509
  7. *
  8. * Author : Christophe Clavier
  9. *
  10. * Modify : Laurent CASSIER
  11. *
  12. * Compiler : Microsoft Visual C 5.0
  13. *
  14. * Host : IBM PC and compatible machines under Windows 95.
  15. *
  16. * Release : 1.10.001
  17. *
  18. * Last Modif : 04/03/98: V1.10.001 - Change dictionary management and add
  19. * CC_Init(), CC_Exit() functions.
  20. * 30/01/98: V1.00.005 - Cancel (_OPT_HEADER) the modification in
  21. * the length of subjectPKInfo and signature
  22. * made in the previous version.
  23. * 28/01/98: V1.00.004 - Allows up to 32767 entries in the dictionary
  24. * and stores the length of the subjectPKInfo
  25. * and signature on one byte instead of two if
  26. * it is less than 128.
  27. * 13/01/98: V1.00.003 - Modify for meta-compression and dictionary
  28. * version ascending compatibility.
  29. * 11/12/97: V1.00.002 - Modify for new dictionary format
  30. * and compatible with CSP and PKCS.
  31. * 27/08/97: V1.00.001 - First implementation.
  32. *
  33. ********************************************************************************
  34. *
  35. * Warning :
  36. *
  37. * Remark : Flags de compilations :
  38. *
  39. * - _STUDY : Lorsqu'il est dfini, des fichiers de log utiles
  40. * lors de l'tude de l'efficacit des algos
  41. * de compression. sont gnrs.
  42. *
  43. * - _TRICKY_COMPRESSION : Lorsqu'il est dfini, on ne tente pas
  44. * de compresser les champs
  45. * 'subjectPublicKey' et 'signature' qui
  46. * sont essentiellement alatoires.
  47. *
  48. * - _OPT_HEADER : Lorsqu'il est dfini, et si _TRICKY_COMPRESSION
  49. * est dfini galement, le header de longueur des
  50. * compresss de subjectPKInfo et de signature
  51. * sont optimiss pour ne tenir sur un seul octet
  52. * si la longueur est infrieure 128 au lieu de
  53. * deux octets dans tous les cas sinon.
  54. * Ne pas dfinir ce flag permet d'tre compatible
  55. * avec les versions infrieures 1.00.005
  56. *
  57. * - _GLOBAL_COMPRESSION : Lorsqu'il est dfini, le compress du
  58. * certificat est lui mme envoy la
  59. * fonction CC_RawEncode afin d'y appliquer
  60. * le meilleur algo de compression dispo.
  61. *
  62. * - _OPT_HEADER : Lorsqu'il est dfini, l
  63. * certificat est lui mme envoy la
  64. * fonction CC_RawEncode afin d'y appliquer
  65. * le meilleur algo de compression dispo.
  66. *
  67. * - _ALGO_x (x de 1 7) : Lorsqu'il est dfini, l'algo de
  68. * compression numro x est utilis.
  69. *
  70. * Conseils pour la version release de GemPASS :
  71. *
  72. * - _STUDY : non dfini
  73. * - _TRICKY_COMPRESSION : dfini
  74. * - _OPT_HEADER : non dfini
  75. * - _GLOBAL_COMPRESSION : non dfini
  76. * - _ALGO_1 : dfini
  77. * - _ALGO_2 : dfini
  78. * - _ALGO_x (x>2) : non dfini
  79. *
  80. *******************************************************************************/
  81. /*------------------------------------------------------------------------------
  82. Includes files
  83. ------------------------------------------------------------------------------*/
  84. #ifdef _WINDOWS
  85. #include <windows.h>
  86. #endif
  87. #include <stdio.h>
  88. #include <io.h>
  89. #include <fcntl.h>
  90. #include <sys/types.h>
  91. #include <sys/stat.h>
  92. #include "ccdef.h"
  93. #include "ac.h"
  94. #include "compcert.h"
  95. #include "gmem.h"
  96. #include "resource.h"
  97. extern HINSTANCE g_hInstRes;
  98. /*------------------------------------------------------------------------------
  99. Information section
  100. ------------------------------------------------------------------------------*/
  101. #define G_NAME "COMPCERT"
  102. #define G_RELEASE "1.10.001"
  103. /*------------------------------------------------------------------------------
  104. Static Variables
  105. ------------------------------------------------------------------------------*/
  106. USHORT NbDaysInMonth[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
  107. char* AlgorithmTypeDict[] = {
  108. /* x9-57 */
  109. "\x2A\x86\x48\xCE\x38\x02\x01", /*x9.57-holdinstruction-none (1 2 840 10040 2 1) */
  110. "\x2A\x86\x48\xCE\x38\x02\x02", /*x9.57-holdinstruction-callissuer (1 2 840 10040 2 2) */
  111. "\x2A\x86\x48\xCE\x38\x02\x03", /*x9.57-holdinstruction-reject (1 2 840 10040 2 3) */
  112. "\x2A\x86\x48\xCE\x38\x04\x01", /*x9.57-dsa (1 2 840 10040 4 1) */
  113. "\x2A\x86\x48\xCE\x38\x04\x03", /*x9.57-dsaWithSha1 (1 2 840 10040 4 3) */
  114. /* x9-42 */
  115. "\x2A\x86\x48\xCE\x3E\x02\x01", /*x9.42-dhPublicNumber (1 2 840 10046 2 1) */
  116. /* Nortel Secure Networks */
  117. "\x2A\x86\x48\x86\xF6\x7D\x07\x42", /*nsn-alg (1 2 840 113533 7 66) */
  118. "\x2A\x86\x48\x86\xF6\x7D\x07\x42\x0A", /*nsn-alg-cast5CBC (1 2 840 113533 7 66 10) */
  119. "\x2A\x86\x48\x86\xF6\x7D\x07\x42\x0B", /*nsn-alg-cast5MAC (1 2 840 113533 7 66 11) */
  120. "\x2A\x86\x48\x86\xF6\x7D\x07\x42\x0C", /*nsn-alg-pbeWithMD5AndCAST5-CBC (1 2 840 113533 7 66 12) */
  121. /* PKCS #1 */
  122. "\x2A\x86\x48\x86\xF7\x0D\x01\x01", /*pkcs-1 (1 2 840 113549 1 1) */
  123. "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01", /*pkcs-1-rsaEncryption (1 2 840 113549 1 1 1) */
  124. "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x02", /*pkcs-1-MD2withRSAEncryption (1 2 840 113549 1 1 2) */
  125. "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x03", /*pkcs-1-MD4withRSAEncryption (1 2 840 113549 1 1 3) */
  126. "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x04", /*pkcs-1-MD5withRSAEncryption (1 2 840 113549 1 1 4) */
  127. "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05", /*pkcs-1-SHA1withRSAEncryption (1 2 840 113549 1 1 5) */
  128. /*need to determine which of the following 2 is correct */
  129. /*"\x2A\x86\x48\x86\xF7\x0D\x01\x01\x06", pkcs-1-ripemd160WithRSAEncryption (1 2 840 113549 1 1 6) */
  130. "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x06", /*pkcs-1-rsaOAEPEncryptionSET (1 2 840 113549 1 1 6) */
  131. /* PKCS #3 */
  132. "\x2A\x86\x48\x86\xF7\x0D\x01\x03", /*pkcs-3 (1 2 840 113549 1 3) */
  133. "\x2A\x86\x48\x86\xF7\x0D\x01\x03\x01", /*pkcs-3-dhKeyAgreement (1 2 840 113549 1 3 1) */
  134. /* PKCS #5 */
  135. "\x2A\x86\x48\x86\xF7\x0D\x01\x05", /*pkcs-5 (1 2 840 113549 1 5) */
  136. "\x2A\x86\x48\x86\xF7\x0D\x01\x05\x01", /*pkcs-5-pbeWithMD2AndDES-CBC (1 2 840 113549 1 5 1) */
  137. "\x2A\x86\x48\x86\xF7\x0D\x01\x05\x03", /*pkcs-5-pbeWithMD5AndDES-CBC (1 2 840 113549 1 5 3) */
  138. "\x2A\x86\x48\x86\xF7\x0D\x01\x05\x04", /*pkcs-5-pbeWithMD2AndRC2-CBC (1 2 840 113549 1 5 4) */
  139. "\x2A\x86\x48\x86\xF7\x0D\x01\x05\x06", /*pkcs-5-pbeWithMD5AndRC2-CBC (1 2 840 113549 1 5 6) */
  140. "\x2A\x86\x48\x86\xF7\x0D\x01\x05\x09", /*pkcs-5-pbeWithMD5AndXOR (1 2 840 113549 1 5 9) */
  141. "\x2A\x86\x48\x86\xF7\x0D\x01\x05\x0A", /*pkcs-5-pbeWithSHA1AndDES-CBC (1 2 840 113549 1 5 10) */
  142. /* PKCS #12 */
  143. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C", /*pkcs-12 (1 2 840 113549 1 12) */
  144. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x01", /*pkcs-12-modeID (1 2 840 113549 1 12 1) */
  145. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x01\x01", /*pkcs-12-OfflineTransportMode (1 2 840 113549 1 12 1 1) */
  146. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x01\x02", /*pkcs-12-OnlineTransportMode (1 2 840 113549 1 12 1 2) */
  147. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x02", /*pkcs-12-ESPVKID (1 2 840 113549 1 12 2) */
  148. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x02\x01", /*pkcs-12-PKCS8KeyShrouding (1 2 840 113549 1 12 2 1) */
  149. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x03", /*pkcs-12-BagID (1 2 840 113549 1 12 3) */
  150. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x03\x01", /*pkcs-12-KeyBagID (1 2 840 113549 1 12 3 1) */
  151. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x03\x02", /*pkcs-12-CertAndCRLBagID (1 2 840 113549 1 12 3 2) */
  152. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x03\x03", /*pkcs-12-SecretBagID (1 2 840 113549 1 12 3 3) */
  153. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x04", /*pkcs-12-CertBagID (1 2 840 113549 1 12 4) */
  154. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x04\x01", /*pkcs-12-X509CertCRLBag (1 2 840 113549 1 12 4 1) */
  155. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x04\x02", /*pkcs-12-SDSICertBag (1 2 840 113549 1 12 4 2) */
  156. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05", /*pkcs-12-OID (1 2 840 113549 1 12 5) */
  157. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01", /*pkcs-12-PBEID (1 2 840 113549 1 12 5 1) */
  158. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01\x01", /*pkcs-12-PBEWithSha1And128BitRC4 (1 2 840 113549 1 12 5 1 1) */
  159. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01\x02", /*pkcs-12-PBEWithSha1And40BitRC4 (1 2 840 113549 1 12 5 1 2) */
  160. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01\x03", /*pkcs-12-PBEWithSha1AndTripleDESCBC (1 2 840 113549 1 12 5 1 3) */
  161. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01\x04", /*pkcs-12-PBEWithSha1And128BitRC2CBC (1 2 840 113549 1 12 5 1 4) */
  162. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01\x05", /*pkcs-12-PBEWithSha1And40BitRC2CBC (1 2 840 113549 1 12 5 1 5) */
  163. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01\x06", /*pkcs-12-PBEWithSha1AndRC4 (1 2 840 113549 1 12 5 1 6) */
  164. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01\x07", /*pkcs-12-PBEWithSha1AndRC2CBC (1 2 840 113549 1 12 5 1 7) */
  165. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x02", /*pkcs-12-EnvelopingID (1 2 840 113549 1 12 5 2) */
  166. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x02\x01", /*pkcs-12-RSAEncryptionWith128BitRC4 (1 2 840 113549 1 12 5 2 1) */
  167. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x02\x02", /*pkcs-12-RSAEncryptionWith40BitRC4 (1 2 840 113549 1 12 5 2 2) */
  168. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x02\x03", /*pkcs-12-RSAEncryptionWithTripleDES (1 2 840 113549 1 12 5 2 3) */
  169. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x03", /*pkcs-12-SignatureID (1 2 840 113549 1 12 5 3) */
  170. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x03\x01", /*pkcs-12-RSASignatureWithSHA1Digest (1 2 840 113549 1 12 5 3 1) */
  171. /* RSADSI digest algorithms */
  172. "\x2A\x86\x48\x86\xF7\x0D\x02", /*RSADSI-digestAlgorithm (1 2 840 113549 2) */
  173. "\x2A\x86\x48\x86\xF7\x0D\x02\x02", /*RSADSI-md2 (1 2 840 113549 2 2) */
  174. "\x2A\x86\x48\x86\xF7\x0D\x02\x04", /*RSADSI-md4 (1 2 840 113549 2 4) */
  175. "\x2A\x86\x48\x86\xF7\x0D\x02\x05", /*RSADSI-md5 (1 2 840 113549 2 5) */
  176. /* RSADSI encryption algorithms */
  177. "\x2A\x86\x48\x86\xF7\x0D\x03", /*RSADSI-encryptionAlgorithm (1 2 840 113549 3) */
  178. "\x2A\x86\x48\x86\xF7\x0D\x03\x02", /*RSADSI-rc2CBC (1 2 840 113549 3 2) */
  179. "\x2A\x86\x48\x86\xF7\x0D\x03\x03", /*RSADSI-rc2ECB (1 2 840 113549 3 3) */
  180. "\x2A\x86\x48\x86\xF7\x0D\x03\x04", /*RSADSI-rc4 (1 2 840 113549 3 4) */
  181. "\x2A\x86\x48\x86\xF7\x0D\x03\x05", /*RSADSI-rc4WithMAC (1 2 840 113549 3 5) */
  182. "\x2A\x86\x48\x86\xF7\x0D\x03\x06", /*RSADSI-DESX-CBC (1 2 840 113549 3 6) */
  183. "\x2A\x86\x48\x86\xF7\x0D\x03\x07", /*RSADSI-DES-EDE3-CBC (1 2 840 113549 3 7) */
  184. "\x2A\x86\x48\x86\xF7\x0D\x03\x08", /*RSADSI-RC5CBC (1 2 840 113549 3 8) */
  185. "\x2A\x86\x48\x86\xF7\x0D\x03\x09", /*RSADSI-RC5CBCPad (1 2 840 113549 3 9) */
  186. "\x2A\x86\x48\x86\xF7\x0D\x03\x0A", /*RSADSI-CDMFCBCPad (1 2 840 113549 3 10) */
  187. /* cryptlib */
  188. "\x2B\x06\x01\x04\x01\x97\x55\x20\x01", /*cryptlibEnvelope (1 3 6 1 4 1 3029 32 1) */
  189. /* Not sure about these ones: */
  190. /*"\x2B\x0E\x02\x1A\x05", sha (1 3 14 2 26 5) */
  191. /*"\x2B\x0E\x03\x02\x01\x01", rsa (1 3 14 3 2 1 1) */ //X-509
  192. /*"\x2B\x0E\x03\x02\x02\x01", sqmod-N (1 3 14 3 2 2 1) */ //X-509
  193. /*"\x2B\x0E\x03\x02\x03\x01", sqmod-NwithRSA (1 3 14 3 2 3 1) */ //X-509
  194. /* Miscellaneous partially-defunct OIW semi-standards aka algorithms */
  195. "\x2B\x0E\x03\x02\x02", /*ISO-algorithm-md4WitRSA (1 3 14 3 2 2) */
  196. "\x2B\x0E\x03\x02\x03", /*ISO-algorithm-md5WithRSA (1 3 14 3 2 3) */
  197. "\x2B\x0E\x03\x02\x04", /*ISO-algorithm-md4WithRSAEncryption (1 3 14 3 2 4) */
  198. "\x2B\x0E\x03\x02\x06", /*ISO-algorithm-desECB (1 3 14 3 2 6) */
  199. "\x2B\x0E\x03\x02\x07", /*ISO-algorithm-desCBC (1 3 14 3 2 7) */
  200. "\x2B\x0E\x03\x02\x08", /*ISO-algorithm-desOFB (1 3 14 3 2 8) */
  201. "\x2B\x0E\x03\x02\x09", /*ISO-algorithm-desCFB (1 3 14 3 2 9) */
  202. "\x2B\x0E\x03\x02\x0A", /*ISO-algorithm-desMAC (1 3 14 3 2 10) */
  203. "\x2B\x0E\x03\x02\x0B", /*ISO-algorithm-rsaSignature (1 3 14 3 2 11) */ //ISO 9796
  204. "\x2B\x0E\x03\x02\x0C", /*ISO-algorithm-dsa (1 3 14 3 2 12) */
  205. "\x2B\x0E\x03\x02\x0D", /*ISO-algorithm-dsaWithSHA (1 3 14 3 2 13) */
  206. "\x2B\x0E\x03\x02\x0E", /*ISO-algorithm-mdc2WithRSASignature (1 3 14 3 2 14) */
  207. "\x2B\x0E\x03\x02\x0F", /*ISO-algorithm-shaWithRSASignature (1 3 14 3 2 15) */
  208. "\x2B\x0E\x03\x02\x10", /*ISO-algorithm-dhWithCommonModulus (1 3 14 3 2 16) */
  209. "\x2B\x0E\x03\x02\x11", /*ISO-algorithm-desEDE (1 3 14 3 2 17) */
  210. "\x2B\x0E\x03\x02\x12", /*ISO-algorithm-sha (1 3 14 3 2 18) */
  211. "\x2B\x0E\x03\x02\x13", /*ISO-algorithm-mdc-2 (1 3 14 3 2 19) */
  212. "\x2B\x0E\x03\x02\x14", /*ISO-algorithm-dsaCommon (1 3 14 3 2 20) */
  213. "\x2B\x0E\x03\x02\x15", /*ISO-algorithm-dsaCommonWithSHA (1 3 14 3 2 21) */
  214. "\x2B\x0E\x03\x02\x16", /*ISO-algorithm-rsaKeyTransport (1 3 14 3 2 22) */
  215. "\x2B\x0E\x03\x02\x17", /*ISO-algorithm-keyed-hash-seal (1 3 14 3 2 23) */
  216. "\x2B\x0E\x03\x02\x18", /*ISO-algorithm-md2WithRSASignature (1 3 14 3 2 24) */
  217. "\x2B\x0E\x03\x02\x19", /*ISO-algorithm-md5WithRSASignature (1 3 14 3 2 25) */
  218. "\x2B\x0E\x03\x02\x1A", /*ISO-algorithm-sha1 (1 3 14 3 2 26) */
  219. "\x2B\x0E\x03\x02\x1B", /*ISO-algorithm-ripemd160 (1 3 14 3 2 27) */
  220. "\x2B\x0E\x03\x02\x1D", /*ISO-algorithm-sha-1WithRSAEncryption (1 3 14 3 2 29) */
  221. "\x2B\x0E\x03\x03\x01", /*ISO-algorithm-simple-strong-auth-mechanism (1 3 14 3 3 1) */
  222. /* Not sure about these ones:
  223. /*"\x2B\x0E\x07\x02\x01\x01", ElGamal (1 3 14 7 2 1 1) */
  224. /*"\x2B\x0E\x07\x02\x03\x01", md2WithRSA (1 3 14 7 2 3 1) */
  225. /*"\x2B\x0E\x07\x02\x03\x02", md2WithElGamal (1 3 14 7 2 3 2) */
  226. /* X500 algorithms */
  227. "\x55\x08", /*X500-Algorithms (2 5 8) */
  228. "\x55\x08\x01", /*X500-Alg-Encryption (2 5 8 1) */
  229. "\x55\x08\x01\x01", /*rsa (2 5 8 1 1) */
  230. /* DMS-SDN-702 */
  231. "\x60\x86\x48\x01\x65\x02\x01\x01\x01", /*id-sdnsSignatureAlgorithm (2 16 840 1 101 2 1 1 1) */
  232. "\x60\x86\x48\x01\x65\x02\x01\x01\x02", /*id-mosaicSignatureAlgorithm (2 16 840 1 101 2 1 1 2) */
  233. "\x60\x86\x48\x01\x65\x02\x01\x01\x03", /*id-sdnsConfidentialityAlgorithm (2 16 840 1 101 2 1 1 3) */
  234. "\x60\x86\x48\x01\x65\x02\x01\x01\x04", /*id-mosaicConfidentialityAlgorithm (2 16 840 1 101 2 1 1 4) */
  235. "\x60\x86\x48\x01\x65\x02\x01\x01\x05", /*id-sdnsIntegrityAlgorithm (2 16 840 1 101 2 1 1 5) */
  236. "\x60\x86\x48\x01\x65\x02\x01\x01\x06", /*id-mosaicIntegrityAlgorithm (2 16 840 1 101 2 1 1 6) */
  237. "\x60\x86\x48\x01\x65\x02\x01\x01\x07", /*id-sdnsTokenProtectionAlgorithm (2 16 840 1 101 2 1 1 7) */
  238. "\x60\x86\x48\x01\x65\x02\x01\x01\x08", /*id-mosaicTokenProtectionAlgorithm (2 16 840 1 101 2 1 1 8) */
  239. "\x60\x86\x48\x01\x65\x02\x01\x01\x09", /*id-sdnsKeyManagementAlgorithm (2 16 840 1 101 2 1 1 9) */
  240. "\x60\x86\x48\x01\x65\x02\x01\x01\x0A", /*id-mosaicKeyManagementAlgorithm (2 16 840 1 101 2 1 1 10) */
  241. "\x60\x86\x48\x01\x65\x02\x01\x01\x0B", /*id-sdnsKMandSigAlgorithm (2 16 840 1 101 2 1 1 11) */
  242. "\x60\x86\x48\x01\x65\x02\x01\x01\x0C", /*id-mosaicKMandSigAlgorithm (2 16 840 1 101 2 1 1 12) */
  243. "\x60\x86\x48\x01\x65\x02\x01\x01\x0D", /*id-SuiteASignatureAlgorithm (2 16 840 1 101 2 1 1 13) */
  244. "\x60\x86\x48\x01\x65\x02\x01\x01\x0E", /*id-SuiteAConfidentialityAlgorithm (2 16 840 1 101 2 1 1 14) */
  245. "\x60\x86\x48\x01\x65\x02\x01\x01\x0F", /*id-SuiteAIntegrityAlgorithm (2 16 840 1 101 2 1 1 15) */
  246. "\x60\x86\x48\x01\x65\x02\x01\x01\x10", /*id-SuiteATokenProtectionAlgorithm (2 16 840 1 101 2 1 1 16) */
  247. "\x60\x86\x48\x01\x65\x02\x01\x01\x11", /*id-SuiteAKeyManagementAlgorithm (2 16 840 1 101 2 1 1 17) */
  248. "\x60\x86\x48\x01\x65\x02\x01\x01\x12", /*id-SuiteAKMandSigAlgorithm (2 16 840 1 101 2 1 1 18) */
  249. "\x60\x86\x48\x01\x65\x02\x01\x01\x13", /*id-mosaicUpdatedSigAlgorithm (2 16 840 1 101 2 1 1 19) */
  250. "\x60\x86\x48\x01\x65\x02\x01\x01\x14", /*id-mosaicKMandUpdSigAlgorithms (2 16 840 1 101 2 1 1 20) */
  251. "\x60\x86\x48\x01\x65\x02\x01\x01\x15", /*id-mosaicUpdatedIntegAlgorithm (2 16 840 1 101 2 1 1 21) */
  252. "\x60\x86\x48\x01\x65\x02\x01\x01\x16", /*id-mosaicKeyEncryptionAlgorithm (2 16 840 1 101 2 1 1 22) */
  253. NULL
  254. };
  255. char* AttributeTypeDict[] = {
  256. /* x9-57 */
  257. "\x2A\x86\x48\xCE\x38\x02\x01", /*x9.57-holdinstruction-none (1 2 840 10040 2 1) */
  258. "\x2A\x86\x48\xCE\x38\x02\x02", /*x9.57-holdinstruction-callissuer (1 2 840 10040 2 2) */
  259. "\x2A\x86\x48\xCE\x38\x02\x03", /*x9.57-holdinstruction-reject (1 2 840 10040 2 3) */
  260. "\x2A\x86\x48\xCE\x38\x04\x01", /*x9.57-dsa (1 2 840 10040 4 1) */
  261. "\x2A\x86\x48\xCE\x38\x04\x03", /*x9.57-dsaWithSha1 (1 2 840 10040 4 3) */
  262. /* x9-42 */
  263. "\x2A\x86\x48\xCE\x3E\x02\x01", /*x9.42-dhPublicNumber (1 2 840 10046 2 1) */
  264. /* Nortel Secure Networks */
  265. "\x2A\x86\x48\x86\xF6\x7D\x07", /*nsn (1 2 840 113533 7) */
  266. "\x2A\x86\x48\x86\xF6\x7D\x07\x41\x00", /*nsn-ce-entrustVersInfo (1 2 840 113533 7 65 0) */
  267. "\x2A\x86\x48\x86\xF6\x7D\x07\x41", /*nsn-ce (1 2 840 113533 7 65) */
  268. "\x2A\x86\x48\x86\xF6\x7D\x07\x42", /*nsn-alg (1 2 840 113533 7 66) */
  269. "\x2A\x86\x48\x86\xF6\x7D\x07\x42\x0A", /*nsn-alg-cast5CBC (1 2 840 113533 7 66 10) */
  270. "\x2A\x86\x48\x86\xF6\x7D\x07\x42\x0B", /*nsn-alg-cast5MAC (1 2 840 113533 7 66 11) */
  271. "\x2A\x86\x48\x86\xF6\x7D\x07\x42\x0C", /*nsn-alg-pbeWithMD5AndCAST5-CBC (1 2 840 113533 7 66 12) */
  272. "\x2A\x86\x48\x86\xF6\x7D\x07\x43", /*nsn-oc (1 2 840 113533 7 67) */
  273. "\x2A\x86\x48\x86\xF6\x7D\x07\x43\x0C", /*nsn-oc-entrustUser (1 2 840 113533 7 67 0) */
  274. "\x2A\x86\x48\x86\xF6\x7D\x07\x44\x00", /*nsn-at-entrustCAInfo (1 2 840 113533 7 68 0) */
  275. "\x2A\x86\x48\x86\xF6\x7D\x07\x44\x0A", /*nsn-at-attributeCertificate (1 2 840 113533 7 68 10) */
  276. "\x2A\x86\x48\x86\xF6\x7D\x07\x44", /*nsn-at (1 2 840 113533 7 68) */
  277. /* PKCS #1 */
  278. "\x2A\x86\x48\x86\xF7\x0D\x01\x01", /*pkcs-1 (1 2 840 113549 1 1) */
  279. "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01", /*pkcs-1-rsaEncryption (1 2 840 113549 1 1 1) */
  280. "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x02", /*pkcs-1-MD2withRSAEncryption (1 2 840 113549 1 1 2) */
  281. "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x03", /*pkcs-1-MD4withRSAEncryption (1 2 840 113549 1 1 3) */
  282. "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x04", /*pkcs-1-MD5withRSAEncryption (1 2 840 113549 1 1 4) */
  283. "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05", /*pkcs-1-SHA1withRSAEncryption (1 2 840 113549 1 1 5) */
  284. /*need to determine which of the following 2 is correct */
  285. /*"\x2A\x86\x48\x86\xF7\x0D\x01\x01\x06", pkcs-1-ripemd160WithRSAEncryption (1 2 840 113549 1 1 6) */
  286. "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x06", /*pkcs-1-rsaOAEPEncryptionSET (1 2 840 113549 1 1 6) */
  287. /* PKCS #3 */
  288. "\x2A\x86\x48\x86\xF7\x0D\x01\x03", /*pkcs-3 (1 2 840 113549 1 3) */
  289. "\x2A\x86\x48\x86\xF7\x0D\x01\x03\x01", /*pkcs-3-dhKeyAgreement (1 2 840 113549 1 3 1) */
  290. /* PKCS #5 */
  291. "\x2A\x86\x48\x86\xF7\x0D\x01\x05", /*pkcs-5 (1 2 840 113549 1 5) */
  292. "\x2A\x86\x48\x86\xF7\x0D\x01\x05\x01", /*pkcs-5-pbeWithMD2AndDES-CBC (1 2 840 113549 1 5 1) */
  293. "\x2A\x86\x48\x86\xF7\x0D\x01\x05\x03", /*pkcs-5-pbeWithMD5AndDES-CBC (1 2 840 113549 1 5 3) */
  294. "\x2A\x86\x48\x86\xF7\x0D\x01\x05\x04", /*pkcs-5-pbeWithMD2AndRC2-CBC (1 2 840 113549 1 5 4) */
  295. "\x2A\x86\x48\x86\xF7\x0D\x01\x05\x06", /*pkcs-5-pbeWithMD5AndRC2-CBC (1 2 840 113549 1 5 6) */
  296. "\x2A\x86\x48\x86\xF7\x0D\x01\x05\x09", /*pkcs-5-pbeWithMD5AndXOR (1 2 840 113549 1 5 9) */
  297. "\x2A\x86\x48\x86\xF7\x0D\x01\x05\x0A", /*pkcs-5-pbeWithSHA1AndDES-CBC (1 2 840 113549 1 5 10) */
  298. /* PKCS #7 */
  299. "\x2A\x86\x48\x86\xF7\x0D\x01\x07", /*pkcs-7 (1 2 840 113549 1 7) */
  300. "\x2A\x86\x48\x86\xF7\x0D\x01\x07\x01", /*pkcs-7-data (1 2 840 113549 1 7 1) */
  301. "\x2A\x86\x48\x86\xF7\x0D\x01\x07\x02", /*pkcs-7-signedData (1 2 840 113549 1 7 2) */
  302. "\x2A\x86\x48\x86\xF7\x0D\x01\x07\x03", /*pkcs-7-envelopedData (1 2 840 113549 1 7 3) */
  303. "\x2A\x86\x48\x86\xF7\x0D\x01\x07\x04", /*pkcs-7-signedAndEnvelopedData (1 2 840 113549 1 7 4) */
  304. "\x2A\x86\x48\x86\xF7\x0D\x01\x07\x05", /*pkcs-7-digestData (1 2 840 113549 1 7 5) */
  305. "\x2A\x86\x48\x86\xF7\x0D\x01\x07\x06", /*pkcs-7-encryptedData (1 2 840 113549 1 7 6) */
  306. "\x2A\x86\x48\x86\xF7\x0D\x01\x07\x07", /*pkcs-7-dataWithAttributes (1 2 840 113549 1 7 7) */
  307. "\x2A\x86\x48\x86\xF7\x0D\x01\x07\x08", /*pkcs-7-encryptedPrivateKeyInfo (1 2 840 113549 1 7 8) */
  308. /* PKCS #9 */
  309. "\x2A\x86\x48\x86\xF7\x0D\x01\x09", /*pkcs-9 (1 2 840 113549 1 9) */
  310. "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x01", /*pkcs-9-emailAddress (1 2 840 113549 1 9 1) */
  311. "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x02", /*pkcs-9-unstructuredName (1 2 840 113549 1 9 2) */
  312. "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x03", /*pkcs-9-contentType (1 2 840 113549 1 9 3) */
  313. "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x04", /*pkcs-9-messageDigest (1 2 840 113549 1 9 4) */
  314. "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x05", /*pkcs-9-signingTime (1 2 840 113549 1 9 5) */
  315. "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x06", /*pkcs-9-countersignature (1 2 840 113549 1 9 6) */
  316. "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x07", /*pkcs-9-challengePassword (1 2 840 113549 1 9 7) */
  317. "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x08", /*pkcs-9-unstructuredAddress (1 2 840 113549 1 9 8) */
  318. "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x09", /*pkcs-9-extendedCertificateAttributes (1 2 840 113549 1 9 9) */
  319. "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x0A", /*pkcs-9-issuerAndSerialNumber (1 2 840 113549 1 9 10) */
  320. "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x0B", /*pkcs-9-passwordCheck (1 2 840 113549 1 9 11) */
  321. "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x0C", /*pkcs-9-publicKey (1 2 840 113549 1 9 12) */
  322. "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x0D", /*pkcs-9-signingDescription (1 2 840 113549 1 9 13) */
  323. "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x0E", /*pkcs-9-X.509 extension (1 2 840 113549 1 9 14) */
  324. "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x0F", /*pkcs-9-SMIMECapabilities (1 2 840 113549 1 9 15) */
  325. /* PKCS #12 */
  326. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C", /*pkcs-12 (1 2 840 113549 1 12) */
  327. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x01", /*pkcs-12-modeID (1 2 840 113549 1 12 1) */
  328. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x01\x01", /*pkcs-12-OfflineTransportMode (1 2 840 113549 1 12 1 1) */
  329. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x01\x02", /*pkcs-12-OnlineTransportMode (1 2 840 113549 1 12 1 2) */
  330. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x02", /*pkcs-12-ESPVKID (1 2 840 113549 1 12 2) */
  331. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x02\x01", /*pkcs-12-PKCS8KeyShrouding (1 2 840 113549 1 12 2 1) */
  332. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x03", /*pkcs-12-BagID (1 2 840 113549 1 12 3) */
  333. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x03\x01", /*pkcs-12-KeyBagID (1 2 840 113549 1 12 3 1) */
  334. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x03\x02", /*pkcs-12-CertAndCRLBagID (1 2 840 113549 1 12 3 2) */
  335. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x03\x03", /*pkcs-12-SecretBagID (1 2 840 113549 1 12 3 3) */
  336. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x04", /*pkcs-12-CertBagID (1 2 840 113549 1 12 4) */
  337. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x04\x01", /*pkcs-12-X509CertCRLBag (1 2 840 113549 1 12 4 1) */
  338. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x04\x02", /*pkcs-12-SDSICertBag (1 2 840 113549 1 12 4 2) */
  339. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05", /*pkcs-12-OID (1 2 840 113549 1 12 5) */
  340. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01", /*pkcs-12-PBEID (1 2 840 113549 1 12 5 1) */
  341. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01\x01", /*pkcs-12-PBEWithSha1And128BitRC4 (1 2 840 113549 1 12 5 1 1) */
  342. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01\x02", /*pkcs-12-PBEWithSha1And40BitRC4 (1 2 840 113549 1 12 5 1 2) */
  343. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01\x03", /*pkcs-12-PBEWithSha1AndTripleDESCBC (1 2 840 113549 1 12 5 1 3) */
  344. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01\x04", /*pkcs-12-PBEWithSha1And128BitRC2CBC (1 2 840 113549 1 12 5 1 4) */
  345. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01\x05", /*pkcs-12-PBEWithSha1And40BitRC2CBC (1 2 840 113549 1 12 5 1 5) */
  346. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01\x06", /*pkcs-12-PBEWithSha1AndRC4 (1 2 840 113549 1 12 5 1 6) */
  347. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01\x07", /*pkcs-12-PBEWithSha1AndRC2CBC (1 2 840 113549 1 12 5 1 7) */
  348. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x02", /*pkcs-12-EnvelopingID (1 2 840 113549 1 12 5 2) */
  349. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x02\x01", /*pkcs-12-RSAEncryptionWith128BitRC4 (1 2 840 113549 1 12 5 2 1) */
  350. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x02\x02", /*pkcs-12-RSAEncryptionWith40BitRC4 (1 2 840 113549 1 12 5 2 2) */
  351. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x02\x03", /*pkcs-12-RSAEncryptionWithTripleDES (1 2 840 113549 1 12 5 2 3) */
  352. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x03", /*pkcs-12-SignatureID (1 2 840 113549 1 12 5 3) */
  353. "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x03\x01", /*pkcs-12-RSASignatureWithSHA1Digest (1 2 840 113549 1 12 5 3 1) */
  354. /* RSADSI digest algorithms */
  355. "\x2A\x86\x48\x86\xF7\x0D\x02", /*RSADSI-digestAlgorithm (1 2 840 113549 2) */
  356. "\x2A\x86\x48\x86\xF7\x0D\x02\x02", /*RSADSI-md2 (1 2 840 113549 2 2) */
  357. "\x2A\x86\x48\x86\xF7\x0D\x02\x04", /*RSADSI-md4 (1 2 840 113549 2 4) */
  358. "\x2A\x86\x48\x86\xF7\x0D\x02\x05", /*RSADSI-md5 (1 2 840 113549 2 5) */
  359. /* RSADSI encryption algorithms */
  360. "\x2A\x86\x48\x86\xF7\x0D\x03", /*RSADSI-encryptionAlgorithm (1 2 840 113549 3) */
  361. "\x2A\x86\x48\x86\xF7\x0D\x03\x02", /*RSADSI-rc2CBC (1 2 840 113549 3 2) */
  362. "\x2A\x86\x48\x86\xF7\x0D\x03\x03", /*RSADSI-rc2ECB (1 2 840 113549 3 3) */
  363. "\x2A\x86\x48\x86\xF7\x0D\x03\x04", /*RSADSI-rc4 (1 2 840 113549 3 4) */
  364. "\x2A\x86\x48\x86\xF7\x0D\x03\x05", /*RSADSI-rc4WithMAC (1 2 840 113549 3 5) */
  365. "\x2A\x86\x48\x86\xF7\x0D\x03\x06", /*RSADSI-DESX-CBC (1 2 840 113549 3 6) */
  366. "\x2A\x86\x48\x86\xF7\x0D\x03\x07", /*RSADSI-DES-EDE3-CBC (1 2 840 113549 3 7) */
  367. "\x2A\x86\x48\x86\xF7\x0D\x03\x08", /*RSADSI-RC5CBC (1 2 840 113549 3 8) */
  368. "\x2A\x86\x48\x86\xF7\x0D\x03\x09", /*RSADSI-RC5CBCPad (1 2 840 113549 3 9) */
  369. "\x2A\x86\x48\x86\xF7\x0D\x03\x0A", /*RSADSI-CDMFCBCPad (1 2 840 113549 3 10) */
  370. /* Microsoft OIDs */
  371. "\x2A\x86\x48\x86\xF7\x14\x04\x03", /*microsoftExcel (1 2 840 113556 4 3) */
  372. "\x2A\x86\x48\x86\xF7\x14\x04\x04", /*titledWithOID (1 2 840 113556 4 4) */
  373. "\x2A\x86\x48\x86\xF7\x14\x04\x05", /*microsoftPowerPoint (1 2 840 113556 4 5) */
  374. /* cryptlib */
  375. "\x2B\x06\x01\x04\x01\x97\x55\x20\x01", /*cryptlibEnvelope (1 3 6 1 4 1 3029 32 1) */
  376. /* PKIX */
  377. "\x2B\x06\x01\x05\x05\x07", /*pkix-oid (1 3 6 1 5 5 7) */
  378. "\x2B\x06\x01\x05\x05\x07\x01", /*pkix-subjectInfoAccess (1 3 6 1 5 5 7 1) */
  379. "\x2B\x06\x01\x05\x05\x07\x02", /*pkix-authorityInfoAccess (1 3 6 1 5 5 7 2) */
  380. "\x2B\x06\x01\x05\x05\x07\x04", /*pkix-cps (1 3 6 1 5 5 7 4) */
  381. "\x2B\x06\x01\x05\x05\x07\x05", /*pkix-userNotice (1 3 6 1 5 5 7 5) */
  382. /* Not sure about these ones: */
  383. /*"\x2B\x0E\x02\x1A\x05", sha (1 3 14 2 26 5) */
  384. /*"\x2B\x0E\x03\x02\x01\x01", rsa (1 3 14 3 2 1 1) */ //X-509
  385. /*"\x2B\x0E\x03\x02\x02\x01", sqmod-N (1 3 14 3 2 2 1) */ //X-509
  386. /*"\x2B\x0E\x03\x02\x03\x01", sqmod-NwithRSA (1 3 14 3 2 3 1) */ //X-509
  387. /* Miscellaneous partially-defunct OIW semi-standards aka algorithms */
  388. "\x2B\x0E\x03\x02\x02", /*ISO-algorithm-md4WitRSA (1 3 14 3 2 2) */
  389. "\x2B\x0E\x03\x02\x03", /*ISO-algorithm-md5WithRSA (1 3 14 3 2 3) */
  390. "\x2B\x0E\x03\x02\x04", /*ISO-algorithm-md4WithRSAEncryption (1 3 14 3 2 4) */
  391. "\x2B\x0E\x03\x02\x06", /*ISO-algorithm-desECB (1 3 14 3 2 6) */
  392. "\x2B\x0E\x03\x02\x07", /*ISO-algorithm-desCBC (1 3 14 3 2 7) */
  393. "\x2B\x0E\x03\x02\x08", /*ISO-algorithm-desOFB (1 3 14 3 2 8) */
  394. "\x2B\x0E\x03\x02\x09", /*ISO-algorithm-desCFB (1 3 14 3 2 9) */
  395. "\x2B\x0E\x03\x02\x0A", /*ISO-algorithm-desMAC (1 3 14 3 2 10) */
  396. "\x2B\x0E\x03\x02\x0B", /*ISO-algorithm-rsaSignature (1 3 14 3 2 11) */ //ISO 9796
  397. "\x2B\x0E\x03\x02\x0C", /*ISO-algorithm-dsa (1 3 14 3 2 12) */
  398. "\x2B\x0E\x03\x02\x0D", /*ISO-algorithm-dsaWithSHA (1 3 14 3 2 13) */
  399. "\x2B\x0E\x03\x02\x0E", /*ISO-algorithm-mdc2WithRSASignature (1 3 14 3 2 14) */
  400. "\x2B\x0E\x03\x02\x0F", /*ISO-algorithm-shaWithRSASignature (1 3 14 3 2 15) */
  401. "\x2B\x0E\x03\x02\x10", /*ISO-algorithm-dhWithCommonModulus (1 3 14 3 2 16) */
  402. "\x2B\x0E\x03\x02\x11", /*ISO-algorithm-desEDE (1 3 14 3 2 17) */
  403. "\x2B\x0E\x03\x02\x12", /*ISO-algorithm-sha (1 3 14 3 2 18) */
  404. "\x2B\x0E\x03\x02\x13", /*ISO-algorithm-mdc-2 (1 3 14 3 2 19) */
  405. "\x2B\x0E\x03\x02\x14", /*ISO-algorithm-dsaCommon (1 3 14 3 2 20) */
  406. "\x2B\x0E\x03\x02\x15", /*ISO-algorithm-dsaCommonWithSHA (1 3 14 3 2 21) */
  407. "\x2B\x0E\x03\x02\x16", /*ISO-algorithm-rsaKeyTransport (1 3 14 3 2 22) */
  408. "\x2B\x0E\x03\x02\x17", /*ISO-algorithm-keyed-hash-seal (1 3 14 3 2 23) */
  409. "\x2B\x0E\x03\x02\x18", /*ISO-algorithm-md2WithRSASignature (1 3 14 3 2 24) */
  410. "\x2B\x0E\x03\x02\x19", /*ISO-algorithm-md5WithRSASignature (1 3 14 3 2 25) */
  411. "\x2B\x0E\x03\x02\x1A", /*ISO-algorithm-sha1 (1 3 14 3 2 26) */
  412. "\x2B\x0E\x03\x02\x1B", /*ISO-algorithm-ripemd160 (1 3 14 3 2 27) */
  413. "\x2B\x0E\x03\x02\x1D", /*ISO-algorithm-sha-1WithRSAEncryption (1 3 14 3 2 29) */
  414. "\x2B\x0E\x03\x03\x01", /*ISO-algorithm-simple-strong-auth-mechanism (1 3 14 3 3 1) */
  415. /* Not sure about these ones:
  416. /*"\x2B\x0E\x07\x02\x01\x01", ElGamal (1 3 14 7 2 1 1) */
  417. /*"\x2B\x0E\x07\x02\x03\x01", md2WithRSA (1 3 14 7 2 3 1) */
  418. /*"\x2B\x0E\x07\x02\x03\x02", md2WithElGamal (1 3 14 7 2 3 2) */
  419. /* X.520 id-at = 2 5 4*/
  420. "\x55\x04\x00", /*X.520-at-objectClass (2 5 4 0) */
  421. "\x55\x04\x01", /*X.520-at-aliasObjectName (2 5 4 1) */
  422. "\x55\x04\x02", /*X.520-at-knowledgeInformation (2 5 4 2) */
  423. "\x55\x04\x03", /*X.520-at-commonName (2 5 4 3) */
  424. "\x55\x04\x04", /*X.520-at-surname (2 5 4 4) */
  425. "\x55\x04\x05", /*X.520-at-serialNumber (2 5 4 5) */
  426. "\x55\x04\x06", /*X.520-at-countryName (2 5 4 6) */
  427. "\x55\x04\x07", /*X.520-at-localityName (2 5 4 7) */
  428. "\x55\x04\x08", /*X.520-at-stateOrProvinceName (2 5 4 8) */
  429. "\x55\x04\x09", /*X.520-at-streetAddress (2 5 4 9) */
  430. "\x55\x04\x0A", /*X.520-at-organizationName (2 5 4 10) */
  431. "\x55\x04\x0B", /*X.520-at-organizationalUnitName (2 5 4 11) */
  432. "\x55\x04\x0C", /*X.520-at-title (2 5 4 12) */
  433. "\x55\x04\x0D", /*X.520-at-description (2 5 4 13) */
  434. "\x55\x04\x0E", /*X.520-at-searchGuide (2 5 4 14) */
  435. "\x55\x04\x0F", /*X.520-at-businessCategory (2 5 4 15) */
  436. "\x55\x04\x10", /*X.520-at-postalAddress (2 5 4 16) */
  437. "\x55\x04\x11", /*X.520-at-postalCode (2 5 4 17) */
  438. "\x55\x04\x12", /*X.520-at-postOfficeBox (2 5 4 18) */
  439. "\x55\x04\x13", /*X.520-at-physicalDeliveryOfficeName (2 5 4 19) */
  440. "\x55\x04\x14", /*X.520-at-telephoneNumber (2 5 4 20) */
  441. "\x55\x04\x15", /*X.520-at-telexNumber (2 5 4 21) */
  442. "\x55\x04\x16", /*X.520-at-teletexTerminalIdentifier (2 5 4 22) */
  443. "\x55\x04\x17", /*X.520-at-facsimileTelephoneNumber (2 5 4 23) */
  444. "\x55\x04\x18", /*X.520-at-x121AddreX.520-at-ss (2 5 4 24) */
  445. "\x55\x04\x19", /*X.520-at-internationalISNNumber (2 5 4 25) */
  446. "\x55\x04\x1A", /*X.520-at-registeredAddress (2 5 4 26) */
  447. "\x55\x04\x1B", /*X.520-at-destinationIndicator (2 5 4 27) */
  448. "\x55\x04\x1C", /*X.520-at-preferredDeliveryMehtod (2 5 4 28) */
  449. "\x55\x04\x1D", /*X.520-at-presentationAddress (2 5 4 29) */
  450. "\x55\x04\x1E", /*X.520-at-supportedApplicationContext (2 5 4 30) */
  451. "\x55\x04\x1F", /*X.520-at-member (2 5 4 31) */
  452. "\x55\x04\x20", /*X.520-at-owner (2 5 4 32) */
  453. "\x55\x04\x21", /*X.520-at-roleOccupant (2 5 4 33) */
  454. "\x55\x04\x22", /*X.520-at-seeAlso (2 5 4 34) */
  455. "\x55\x04\x23", /*X.520-at-userPassword (2 5 4 35) */
  456. "\x55\x04\x24", /*X.520-at-userCertificate (2 5 4 36) */
  457. "\x55\x04\x25", /*X.520-at-CAcertificate (2 5 4 37) */
  458. "\x55\x04\x26", /*X.520-at-authorityRevocationList (2 5 4 38) */
  459. "\x55\x04\x27", /*X.520-at-certifcateRevocationList (2 5 4 39) */
  460. "\x55\x04\x28", /*X.520-at-crossCertificatePair (2 5 4 40) */
  461. "\x55\x04\x34", /*X.520-at-supportedAlgorithms (2 5 4 52) */
  462. "\x55\x04\x35", /*X.520-at-deltaRevocationList (2 5 4 53) */
  463. "\x55\x04\x3A", /*X.520-at-crossCertificatePair (2 5 4 58) */
  464. /* X500 algorithms */
  465. "\x55\x08", /*X500-Algorithms (2 5 8) */
  466. "\x55\x08\x01", /*X500-Alg-Encryption (2 5 8 1) */
  467. "\x55\x08\x01\x01", /*rsa (2 5 8 1 1) */
  468. /* X.509 id-ce = 2 5 29*/
  469. "\x55\x1D\x01", /*X.509-ce-authorityKeyIdentifier (2 5 29 1) */
  470. "\x55\x1D\x02", /*X.509-ce-keyAttributes (2 5 29 2) */
  471. "\x55\x1D\x03", /*X.509-ce-certificatePolicies (2 5 29 3) */
  472. "\x55\x1D\x04", /*X.509-ce-keyUsageRestriction (2 5 29 4) */
  473. "\x55\x1D\x05", /*X.509-ce-policyMapping (2 5 29 5) */
  474. "\x55\x1D\x06", /*X.509-ce-subtreesConstraint (2 5 29 6) */
  475. "\x55\x1D\x07", /*X.509-ce-subjectAltName (2 5 29 7) */
  476. "\x55\x1D\x08", /*X.509-ce-issuerAltName (2 5 29 8) */
  477. "\x55\x1D\x09", /*X.509-ce-subjectDirectoryAttributes (2 5 29 9) */
  478. "\x55\x1D\x0A", /*X.509-ce-basicConstraints x.509 (2 5 29 10) */
  479. "\x55\x1D\x0B", /*X.509-ce-nameConstraints (2 5 29 11) */
  480. "\x55\x1D\x0C", /*X.509-ce-policyConstraints (2 5 29 12) */
  481. "\x55\x1D\x0D", /*X.509-ce-basicConstraints 9.55 (2 5 29 13) */
  482. "\x55\x1D\x0E", /*X.509-ce-subjectKeyIdentifier (2 5 29 14) */
  483. "\x55\x1D\x0F", /*X.509-ce-keyUsage (2 5 29 15) */
  484. "\x55\x1D\x10", /*X.509-ce-privateKeyUsagePeriod (2 5 29 16) */
  485. "\x55\x1D\x11", /*X.509-ce-subjectAltName (2 5 29 17) */
  486. "\x55\x1D\x12", /*X.509-ce-issuerAltName (2 5 29 18) */
  487. "\x55\x1D\x13", /*X.509-ce-basicConstraints (2 5 29 19) */
  488. "\x55\x1D\x14", /*X.509-ce-cRLNumber (2 5 29 20) */
  489. "\x55\x1D\x15", /*X.509-ce-reasonCode (2 5 29 21) */
  490. "\x55\x1D\x17", /*X.509-ce-instructionCode (2 5 29 23) */
  491. "\x55\x1D\x18", /*X.509-ce-invalidityDate (2 5 29 24) */
  492. "\x55\x1D\x1B", /*X.509-ce-deltaCRLIndicator (2 5 29 27) */
  493. "\x55\x1D\x1C", /*X.509-ce-issuingDistributionPoint (2 5 29 28) */
  494. "\x55\x1D\x1D", /*X.509-ce-certificateIssuer (2 5 29 29) */
  495. "\x55\x1D\x1E", /*X.509-ce-nameConstraints (2 5 29 30) */
  496. "\x55\x1D\x1F", /*X.509-ce-cRLDistPoints (2 5 29 31) */
  497. "\x55\x1D\x20", /*X.509-ce-certificatePolicies (2 5 29 32) */
  498. "\x55\x1D\x21", /*X.509-ce-policyMappings (2 5 29 33) */
  499. "\x55\x1D\x23", /*X.509-ce-authorityKeyIdentifier (2 5 29 35) */
  500. "\x55\x1D\x24", /*X.509-ce-policyConstraints (2 5 29 36) */
  501. /* DMS-SDN-702 */
  502. "\x60\x86\x48\x01\x65\x02\x01\x01\x01", /*id-sdnsSignatureAlgorithm (2 16 840 1 101 2 1 1 1) */
  503. "\x60\x86\x48\x01\x65\x02\x01\x01\x02", /*id-mosaicSignatureAlgorithm (2 16 840 1 101 2 1 1 2) */
  504. "\x60\x86\x48\x01\x65\x02\x01\x01\x03", /*id-sdnsConfidentialityAlgorithm (2 16 840 1 101 2 1 1 3) */
  505. "\x60\x86\x48\x01\x65\x02\x01\x01\x04", /*id-mosaicConfidentialityAlgorithm (2 16 840 1 101 2 1 1 4) */
  506. "\x60\x86\x48\x01\x65\x02\x01\x01\x05", /*id-sdnsIntegrityAlgorithm (2 16 840 1 101 2 1 1 5) */
  507. "\x60\x86\x48\x01\x65\x02\x01\x01\x06", /*id-mosaicIntegrityAlgorithm (2 16 840 1 101 2 1 1 6) */
  508. "\x60\x86\x48\x01\x65\x02\x01\x01\x07", /*id-sdnsTokenProtectionAlgorithm (2 16 840 1 101 2 1 1 7) */
  509. "\x60\x86\x48\x01\x65\x02\x01\x01\x08", /*id-mosaicTokenProtectionAlgorithm (2 16 840 1 101 2 1 1 8) */
  510. "\x60\x86\x48\x01\x65\x02\x01\x01\x09", /*id-sdnsKeyManagementAlgorithm (2 16 840 1 101 2 1 1 9) */
  511. "\x60\x86\x48\x01\x65\x02\x01\x01\x0A", /*id-mosaicKeyManagementAlgorithm (2 16 840 1 101 2 1 1 10) */
  512. "\x60\x86\x48\x01\x65\x02\x01\x01\x0B", /*id-sdnsKMandSigAlgorithm (2 16 840 1 101 2 1 1 11) */
  513. "\x60\x86\x48\x01\x65\x02\x01\x01\x0C", /*id-mosaicKMandSigAlgorithm (2 16 840 1 101 2 1 1 12) */
  514. "\x60\x86\x48\x01\x65\x02\x01\x01\x0D", /*id-SuiteASignatureAlgorithm (2 16 840 1 101 2 1 1 13) */
  515. "\x60\x86\x48\x01\x65\x02\x01\x01\x0E", /*id-SuiteAConfidentialityAlgorithm (2 16 840 1 101 2 1 1 14) */
  516. "\x60\x86\x48\x01\x65\x02\x01\x01\x0F", /*id-SuiteAIntegrityAlgorithm (2 16 840 1 101 2 1 1 15) */
  517. "\x60\x86\x48\x01\x65\x02\x01\x01\x10", /*id-SuiteATokenProtectionAlgorithm (2 16 840 1 101 2 1 1 16) */
  518. "\x60\x86\x48\x01\x65\x02\x01\x01\x11", /*id-SuiteAKeyManagementAlgorithm (2 16 840 1 101 2 1 1 17) */
  519. "\x60\x86\x48\x01\x65\x02\x01\x01\x12", /*id-SuiteAKMandSigAlgorithm (2 16 840 1 101 2 1 1 18) */
  520. "\x60\x86\x48\x01\x65\x02\x01\x01\x13", /*id-mosaicUpdatedSigAlgorithm (2 16 840 1 101 2 1 1 19) */
  521. "\x60\x86\x48\x01\x65\x02\x01\x01\x14", /*id-mosaicKMandUpdSigAlgorithms (2 16 840 1 101 2 1 1 20) */
  522. "\x60\x86\x48\x01\x65\x02\x01\x01\x15", /*id-mosaicUpdatedIntegAlgorithm (2 16 840 1 101 2 1 1 21) */
  523. "\x60\x86\x48\x01\x65\x02\x01\x01\x16", /*id-mosaicKeyEncryptionAlgorithm (2 16 840 1 101 2 1 1 22) */
  524. /* Netscape */
  525. "\x60\x86\x48\x01\x86\xF8\x42\x01\x01", /*netscape-cert-type (2 16 840 1 113730 1 1) */
  526. "\x60\x86\x48\x01\x86\xF8\x42\x01\x02", /*netscape-base-url (2 16 840 1 113730 1 2) */
  527. "\x60\x86\x48\x01\x86\xF8\x42\x01\x03", /*netscape-revocation-url (2 16 840 1 113730 1 3) */
  528. "\x60\x86\x48\x01\x86\xF8\x42\x01\x04", /*netscape-ca-revocation-url (2 16 840 1 113730 1 4) */
  529. "\x60\x86\x48\x01\x86\xF8\x42\x02\x05", /*netscape-cert-sequence (2 16 840 1 113730 2 5) */
  530. "\x60\x86\x48\x01\x86\xF8\x42\x02\x06", /*netscape-cert-url (2 16 840 1 113730 2 6) */
  531. "\x60\x86\x48\x01\x86\xF8\x42\x01\x07", /*netscape-renewal-url (2 16 840 1 113730 1 7) */
  532. "\x60\x86\x48\x01\x86\xF8\x42\x01\x08", /*netscape-ca-policy-url (2 16 840 1 113730 1 8) */
  533. "\x60\x86\x48\x01\x86\xF8\x42\x01\x09", /*netscape-HomePage-url (2 16 840 1 113730 1 9) */
  534. "\x60\x86\x48\x01\x86\xF8\x42\x01\x0A", /*netscape-EntityLogo (2 16 840 1 113730 1 10) */
  535. "\x60\x86\x48\x01\x86\xF8\x42\x01\x0B", /*netscape-UserPicture (2 16 840 1 113730 1 11) */
  536. "\x60\x86\x48\x01\x86\xF8\x42\x01\x0C", /*netscape-ssl-server-name (2 16 840 1 113730 1 12) */
  537. "\x60\x86\x48\x01\x86\xF8\x42\x01\x0D", /*netscape-comment (2 16 840 1 113730 1 13) */
  538. "\x60\x86\x48\x01\x86\xF8\x42\x02", /*netscape-data-type (2 16 840 1 113730 2) */
  539. "\x60\x86\x48\x01\x86\xF8\x42\x02\x01", /*netscape-dt-GIF (2 16 840 1 113730 2 1) */
  540. "\x60\x86\x48\x01\x86\xF8\x42\x02\x02", /*netscape-dt-JPEG (2 16 840 1 113730 2 2) */
  541. "\x60\x86\x48\x01\x86\xF8\x42\x02\x03", /*netscape-dt-URL (2 16 840 1 113730 2 3) */
  542. "\x60\x86\x48\x01\x86\xF8\x42\x02\x04", /*netscape-dt-HTML (2 16 840 1 113730 2 4) */
  543. "\x60\x86\x48\x01\x86\xF8\x42\x02\x05", /*netscape-dt-CertSeq (2 16 840 1 113730 2 5) */
  544. "\x60\x86\x48\x01\x86\xF8\x42\x03", /*netscape-directory (2 16 840 1 113730 3) */
  545. /* SET */
  546. "\x86\x8D\x6F\x02", /*hashedRootKey (2 54 1775 2) */
  547. "\x86\x8D\x6F\x03", /*certificateType (2 54 1775 3) */
  548. "\x86\x8D\x6F\x04", /*merchantData (2 54 1775 4) */
  549. "\x86\x8D\x6F\x05", /*cardCertRequired (2 54 1775 5) */
  550. "\x86\x8D\x6F\x06", /*tunneling (2 54 1775 6) */
  551. "\x86\x8D\x6F\x07", /*setQualifier (2 54 1775 7) */
  552. "\x86\x8D\x6F\x63", /*set-data (2 54 1775 99) */
  553. NULL
  554. };
  555. /*------------------------------------------------------------------------------
  556. Global Variables
  557. ------------------------------------------------------------------------------*/
  558. BYTE
  559. *pDictMemory = NULL_PTR,
  560. DictVersion = 0;
  561. BYTE*
  562. dwPtrMax = 0;
  563. USHORT
  564. usDictCount = 0;
  565. #ifdef _STUDY
  566. FILE
  567. *pfdLog,
  568. *pfdLogFreq,
  569. *pfdBinAc256,
  570. *pfdBinAc16,
  571. *pfdBinAc4,
  572. *pfdBinAc2;
  573. int
  574. sum, i,
  575. Ac256[256],
  576. Ac16[16],
  577. Ac4[4],
  578. Ac2[2];
  579. #endif
  580. /*------------------------------------------------------------------------------
  581. Static Functions Declaration
  582. ------------------------------------------------------------------------------*/
  583. static int CC_Comp(BLOC *pCertificate,
  584. BLOC *pCompressedCertificate
  585. );
  586. static int CC_Uncomp(BLOC *pCompressedCertificate,
  587. BLOC *pUncompressedCertificate
  588. );
  589. static int CC_ExtractContent(ASN1 *pAsn1
  590. );
  591. static int CC_BuildAsn1(ASN1 *pAsn1
  592. );
  593. static int SearchDataByIndex(USHORT usIndex,
  594. BYTE *pDict,
  595. BLOC *pOutBloc
  596. );
  597. static int CC_RawEncode(BLOC *pInBloc,
  598. BLOC *pOutBloc,
  599. BOOL bUseDictionnary
  600. );
  601. static int CC_RawDecode(BYTE *pInData,
  602. BLOC *pOutBloc,
  603. USHORT *pLength,
  604. BOOL bUseDictionnary
  605. );
  606. static int CC_GenericCompress(BLOC *pUncompBloc,
  607. BLOC *pCompBloc,
  608. BYTE AlgoID
  609. );
  610. static int CC_GenericUncompress(BLOC *pCompBloc,
  611. BLOC *pUncompBloc,
  612. BYTE AlgoID
  613. );
  614. static int CC_Encode_TBSCertificate(BLOC *pInBloc,
  615. BLOC *pOutBloc
  616. );
  617. static int CC_Encode_CertificateSerialNumber(BLOC *pInBloc,
  618. BLOC *pOutBloc
  619. );
  620. static int CC_Encode_AlgorithmIdentifier(BLOC *pInBloc,
  621. BLOC *pOutBloc
  622. );
  623. static int CC_Encode_Name(BLOC *pInBloc,
  624. BLOC *pOutBloc
  625. );
  626. static int CC_Encode_RDN(BLOC *pInBloc,
  627. BLOC *pOutBloc
  628. );
  629. static int CC_Encode_AVA(BLOC *pInBloc,
  630. BLOC *pOutBloc
  631. );
  632. static int CC_Encode_Validity(BLOC *pInBloc,
  633. BLOC *pOutBloc
  634. );
  635. static int CC_Encode_UTCTime(BLOC *pInBloc,
  636. BLOC *pOutBloc,
  637. BYTE *pFormat
  638. );
  639. static int CC_Encode_SubjectPKInfo(BLOC *pInBloc,
  640. BLOC *pOutBloc
  641. );
  642. static int CC_Encode_UniqueIdentifier(BLOC *pInBloc,
  643. BLOC *pOutBloc
  644. );
  645. static int CC_Encode_Extensions(BLOC *pInBloc,
  646. BLOC *pOutBloc
  647. );
  648. static int CC_Encode_Extension(BLOC *pInBloc,
  649. BLOC *pOutBloc
  650. );
  651. static int CC_Encode_Signature(BLOC *pInBloc,
  652. BLOC *pOutBloc
  653. );
  654. static int CC_Decode_TBSCertificate(BYTE *pInData,
  655. BLOC *pOutBloc,
  656. USHORT *pLength
  657. );
  658. static int CC_Decode_CertificateSerialNumber(BYTE *pInData,
  659. BLOC *pOutBloc,
  660. USHORT *pLength
  661. );
  662. static int CC_Decode_AlgorithmIdentifier(BYTE *pInData,
  663. BLOC *pOutBloc,
  664. USHORT *pLength
  665. );
  666. static int CC_Decode_Name(BYTE *pInData,
  667. BLOC *pOutBloc,
  668. USHORT *pLength
  669. );
  670. static int CC_Decode_RDN(BYTE *pInData,
  671. BLOC *pOutBloc,
  672. USHORT *pLength
  673. );
  674. static int CC_Decode_AVA(BYTE *pInData,
  675. BLOC *pOutBloc,
  676. USHORT *pLength
  677. );
  678. static int CC_Decode_Validity(BYTE *pInData,
  679. BLOC *pOutBloc,
  680. USHORT *pLength
  681. );
  682. static int CC_Decode_UTCTime(BYTE *pInData,
  683. BYTE Format,
  684. BLOC *pOutBloc,
  685. USHORT *pLength
  686. );
  687. static int CC_Decode_SubjectPKInfo(BYTE *pInData,
  688. BLOC *pOutBloc,
  689. USHORT *pLength
  690. );
  691. static int CC_Decode_UniqueIdentifier(BYTE *pInData,
  692. BLOC *pOutBloc,
  693. USHORT *pLength
  694. );
  695. static int CC_Decode_Extensions(BYTE *pInData,
  696. BLOC *pOutBloc,
  697. USHORT *pLength
  698. );
  699. static int CC_Decode_Extension(BYTE *pInData,
  700. BLOC *pOutBloc,
  701. USHORT *pLength
  702. );
  703. static int CC_Decode_Signature(BYTE *pInData,
  704. BLOC *pOutBloc,
  705. USHORT *pLength
  706. );
  707. /*------------------------------------------------------------------------------
  708. * static DWORD get_file_len(BYTE *lpszFileName)
  709. *
  710. * Description : Get length of file.
  711. *
  712. * Remarks : Nothing.
  713. *
  714. * In : lpszFileName = Name of file.
  715. *
  716. * Out : Nothing.
  717. *
  718. * Responses : size of file, -1 if error occur.
  719. *
  720. ------------------------------------------------------------------------------*/
  721. static DWORD get_file_len(BYTE *lpszFileName)
  722. {
  723. int fp;
  724. DWORD nLen;
  725. fp = _open(lpszFileName, O_RDONLY);
  726. if (fp != 0)
  727. {
  728. nLen = _filelength(fp);
  729. _close(fp);
  730. }
  731. else
  732. {
  733. nLen = -1;
  734. }
  735. return(nLen);
  736. }
  737. /*******************************************************************************
  738. * int CC_Init(BYTE bDictMode, BYTE *pszDictName)
  739. *
  740. * Description : Lit le dictionnaire et son numro de version depuis la base de
  741. * registre vers la mmoire.
  742. *
  743. * Remarks :
  744. *
  745. * In :
  746. *
  747. * Out :
  748. *
  749. * Responses :
  750. *
  751. *******************************************************************************/
  752. int CC_Init(BYTE bDictMode, BYTE *pszDictName)
  753. {
  754. switch (bDictMode)
  755. {
  756. #ifndef _STATIC
  757. /* Dictionary read as resource data GPK_X509_DICTIONARY */
  758. case DICT_STANDARD:
  759. {
  760. LPBYTE pbDict;
  761. DWORD cbDict;
  762. HRSRC hRsrc;
  763. HGLOBAL hDict;
  764. hRsrc = FindResource(g_hInstRes,
  765. //MAKEINTRESOURCE(GPK_X509_DICTIONARY),
  766. TEXT("GPK_X509_DICTIONARY"),
  767. RT_RCDATA
  768. );
  769. if (NULL == hRsrc)
  770. {
  771. goto ERROR_INIT;
  772. }
  773. cbDict = SizeofResource(g_hInstRes, hRsrc);
  774. if (0 == cbDict)
  775. {
  776. goto ERROR_INIT;
  777. }
  778. hDict = LoadResource(g_hInstRes, hRsrc);
  779. if (NULL == hDict)
  780. {
  781. goto ERROR_INIT;
  782. }
  783. pbDict = LockResource(hDict);
  784. if (NULL == pbDict)
  785. {
  786. goto ERROR_INIT;
  787. }
  788. DictVersion = *pbDict;
  789. usDictCount = (WORD)cbDict - 1;
  790. pDictMemory = GMEM_Alloc(usDictCount);
  791. if (pDictMemory == NULL)
  792. {
  793. goto ERROR_INIT;
  794. }
  795. memcpy(pDictMemory, &pbDict[1], usDictCount);
  796. return(RV_SUCCESS);
  797. }
  798. break;
  799. #endif
  800. /* Dictionary read as registyry entry in HKEY_LOCAL_MACHINE with key as */
  801. /* pszDictName parameter */
  802. case DICT_REGISTRY:
  803. {
  804. DWORD
  805. err,
  806. dwIgn;
  807. HKEY
  808. hRegKey;
  809. BYTE
  810. *ptr;
  811. if (pszDictName == NULL_PTR)
  812. {
  813. goto ERROR_INIT;
  814. }
  815. err = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  816. (const char *) pszDictName,
  817. 0L,
  818. "",
  819. REG_OPTION_NON_VOLATILE,
  820. KEY_ALL_ACCESS,
  821. NULL,
  822. &hRegKey,
  823. &dwIgn
  824. );
  825. if(err != ERROR_SUCCESS)
  826. {
  827. goto ERROR_INIT;
  828. }
  829. dwIgn = 0;
  830. err = RegQueryValueEx(hRegKey,
  831. "X509 Dictionary",
  832. NULL,
  833. NULL,
  834. NULL,
  835. &dwIgn
  836. );
  837. if(err != ERROR_SUCCESS)
  838. {
  839. RegCloseKey(hRegKey);
  840. goto ERROR_INIT;
  841. }
  842. ptr = GMEM_Alloc(dwIgn);
  843. if (ptr == NULL)
  844. {
  845. RegCloseKey(hRegKey);
  846. goto ERROR_INIT;
  847. }
  848. err = RegQueryValueEx(hRegKey,
  849. "X509 Dictionary",
  850. NULL,
  851. NULL,
  852. ptr,
  853. &dwIgn
  854. );
  855. if(err != ERROR_SUCCESS)
  856. {
  857. RegCloseKey(hRegKey);
  858. GMEM_Free(ptr);
  859. goto ERROR_INIT;
  860. }
  861. DictVersion = (BYTE)ptr[0];
  862. usDictCount = (WORD)dwIgn - 1;
  863. pDictMemory = GMEM_Alloc(usDictCount);
  864. if (pDictMemory == NULL)
  865. {
  866. RegCloseKey(hRegKey);
  867. GMEM_Free(ptr);
  868. goto ERROR_INIT;
  869. }
  870. memcpy(pDictMemory, &ptr[1], usDictCount);
  871. RegCloseKey(hRegKey);
  872. GMEM_Free(ptr);
  873. return(RV_SUCCESS);
  874. }
  875. break;
  876. /* Dictionary read as file in path pszDictName parameter */
  877. case DICT_FILE:
  878. {
  879. DWORD
  880. dwFileLen;
  881. BYTE
  882. *ptr;
  883. FILE
  884. *fp;
  885. if (pszDictName == NULL_PTR)
  886. {
  887. goto ERROR_INIT;
  888. }
  889. dwFileLen = get_file_len(pszDictName);
  890. ptr = GMEM_Alloc(dwFileLen);
  891. if (ptr == NULL)
  892. {
  893. goto ERROR_INIT;
  894. }
  895. fp = fopen(pszDictName, "rb");
  896. if (fp == NULL)
  897. {
  898. GMEM_Free(ptr);
  899. goto ERROR_INIT;
  900. }
  901. if (!fread(ptr, dwFileLen, 1, fp))
  902. {
  903. fclose(fp);
  904. GMEM_Free(ptr);
  905. goto ERROR_INIT;
  906. }
  907. fclose(fp);
  908. DictVersion = (BYTE)ptr[0];
  909. usDictCount = (WORD)dwFileLen - 1;
  910. pDictMemory = GMEM_Alloc(usDictCount);
  911. if (pDictMemory == NULL)
  912. {
  913. GMEM_Free(ptr);
  914. goto ERROR_INIT;
  915. }
  916. memcpy(pDictMemory, &ptr[1], usDictCount);
  917. GMEM_Free(ptr);
  918. return(RV_SUCCESS);
  919. }
  920. break;
  921. default:
  922. break;
  923. }
  924. ERROR_INIT:
  925. DictVersion = 0;
  926. usDictCount = 0;
  927. pDictMemory = NULL_PTR;
  928. return(RV_BAD_DICTIONARY);
  929. }
  930. /*******************************************************************************
  931. * int CC_Exit(void)
  932. *
  933. * Description : Free dictionary.
  934. *
  935. * Remarks :
  936. *
  937. * In :
  938. *
  939. * Out :
  940. *
  941. * Responses :
  942. *
  943. *******************************************************************************/
  944. int CC_Exit(void)
  945. {
  946. DictVersion = 0;
  947. usDictCount = 0;
  948. if (pDictMemory != NULL_PTR)
  949. {
  950. GMEM_Free(pDictMemory);
  951. }
  952. pDictMemory = NULL_PTR;
  953. return(RV_SUCCESS);
  954. }
  955. /*******************************************************************************
  956. * int CC_Compress(BLOC *pCertificate,
  957. * BLOC *pCompressedCertificate
  958. * )
  959. *
  960. * Description : Fonction de mta-compression visible depuis l'extrieur.
  961. * Adapte la sortie en fonction de la faisabilit d'une compression
  962. * suivie d'une dcompression.
  963. *
  964. * Remarks : Le champ pData du bloc d'entre a t allou par la fonction appelant.
  965. * Le champ pData du bloc de sortie est allou ici. Il doit tre
  966. * dsallou par la fonction appelant (sauf si RV_MALLOC_FAILED).
  967. *
  968. * In : *pCert : Bloc mta-compresser
  969. *
  970. * Out : *pCompCert : Bloc 'meta-compress'
  971. * Si problme lors de la compression/decompression : Renvoie le bloc
  972. * d'entre prcd d'un tag spcifique.
  973. * Sinon : Renvoie le bloc compress prcd du numro de version
  974. * du dictionnaire.
  975. *
  976. * Responses : RV_SUCCESS : All is OK.
  977. * RV_COMPRESSION_FAILED : Un problme a eu lieu lors de l'tape
  978. * de compression/dcompression donc le
  979. * bloc de sortie contient le bloc d'entre
  980. * prcd du tag TAG_COMPRESSION_FAILED.
  981. * RV_BLOC_TOO_LONG : Le bloc d'entre *commence* par un certificat
  982. * dont la compression a pu tre inverse.
  983. * Le bloc de sortie contient donc le compress
  984. * de cette partie initiale seulement.
  985. * RV_MALLOC_FAILED : Un malloc a chou au niveau 'mta'. C'est le
  986. * seul rel retour d'erreur.
  987. *
  988. *******************************************************************************/
  989. int CC_Compress(BLOC *pCert,
  990. BLOC *pCompCert
  991. )
  992. {
  993. BLOC
  994. TryCompCert,
  995. TryUncompCert;
  996. TryCompCert.pData = NULL_PTR;
  997. TryCompCert.usLen = 0;
  998. TryUncompCert.pData = NULL_PTR;
  999. TryUncompCert.usLen = 0;
  1000. #ifdef _STUDY
  1001. /* Ouverture des fichiers de log */
  1002. if ((pfdLog = fopen("CompCert.log", "a+")) == 0)
  1003. {
  1004. return(RV_FILE_OPEN_FAILED);
  1005. }
  1006. fprintf(pfdLog, "\n*****************************************************\n");
  1007. if ((pfdBinAc256 = fopen("Freq256.bin", "r+b")) == 0)
  1008. {
  1009. if ((pfdBinAc256 = fopen("Freq256.bin", "w+b")) == 0)
  1010. {
  1011. return(RV_FILE_OPEN_FAILED);
  1012. }
  1013. memset(Ac256, 0x00, 256 * sizeof(int));
  1014. }
  1015. else
  1016. {
  1017. fread(Ac256, sizeof(int), 256, pfdBinAc256);
  1018. }
  1019. if ((pfdBinAc16 = fopen("Freq016.bin", "r+b")) == 0)
  1020. {
  1021. if ((pfdBinAc16 = fopen("Freq016.bin", "w+b")) == 0)
  1022. {
  1023. return(RV_FILE_OPEN_FAILED);
  1024. }
  1025. memset(Ac16, 0x00, 16 * sizeof(int));
  1026. }
  1027. else
  1028. {
  1029. fread(Ac16, sizeof(int), 16, pfdBinAc16);
  1030. }
  1031. if ((pfdBinAc4 = fopen("Freq004.bin", "r+b")) == 0)
  1032. {
  1033. if ((pfdBinAc4 = fopen("Freq004.bin", "w+b")) == 0)
  1034. {
  1035. return(RV_FILE_OPEN_FAILED);
  1036. }
  1037. memset(Ac4, 0x00, 4 * sizeof(int));
  1038. }
  1039. else
  1040. {
  1041. fread(Ac4, sizeof(int), 4, pfdBinAc4);
  1042. }
  1043. if ((pfdBinAc2 = fopen("Freq002.bin", "r+b")) == 0)
  1044. {
  1045. if ((pfdBinAc2 = fopen("Freq002.bin", "w+b")) == 0)
  1046. {
  1047. return(RV_FILE_OPEN_FAILED);
  1048. }
  1049. memset(Ac2, 0x00, 2 * sizeof(int));
  1050. }
  1051. else
  1052. {
  1053. fread(Ac2, sizeof(int), 2, pfdBinAc2);
  1054. }
  1055. #endif
  1056. if (CC_Comp(pCert, &TryCompCert) != RV_SUCCESS)
  1057. {
  1058. /* Si la compression s'est mal pass�e alors on renvoie le fichier
  1059. d'entre en indiquant que le fichier n'est pas compress */
  1060. if (TryCompCert.pData)
  1061. {
  1062. GMEM_Free(TryCompCert.pData);
  1063. TryCompCert.pData = NULL_PTR;
  1064. }
  1065. /* Allocation de la m�moire pour le certificat compress� */
  1066. if (pCompCert->usLen < pCert->usLen + 1)
  1067. {
  1068. pCompCert->usLen = pCert->usLen + 1;
  1069. if (pCompCert->pData)
  1070. {
  1071. return(RV_BUFFER_TOO_SMALL);
  1072. }
  1073. else
  1074. {
  1075. return(RV_SUCCESS);
  1076. }
  1077. }
  1078. pCompCert->usLen = pCert->usLen + 1;
  1079. pCompCert->pData[0] = TAG_COMPRESSION_FAILED;
  1080. if (pCompCert->pData)
  1081. {
  1082. memcpy(&pCompCert->pData[1], pCert->pData, pCert->usLen);
  1083. }
  1084. return(RV_COMPRESSION_FAILED);
  1085. }
  1086. if ( ( (CC_Uncomp(&TryCompCert, &TryUncompCert) != RV_SUCCESS)
  1087. || (pCert->usLen != TryUncompCert.usLen)
  1088. || (memcmp(TryUncompCert.pData, pCert->pData, pCert->usLen) != 0)
  1089. )
  1090. && (memcmp(TryUncompCert.pData, pCert->pData, TryUncompCert.usLen) != 0)
  1091. )
  1092. {
  1093. /* Si la d�compression s'est mal pass�e ou bien si elle n'est pas fid�le
  1094. alors on renvoie le fichier d'entre en indiquant que le fichier
  1095. n'est pas compress */
  1096. if (TryCompCert.pData)
  1097. {
  1098. GMEM_Free(TryCompCert.pData);
  1099. TryCompCert.pData = NULL_PTR;
  1100. }
  1101. if (TryUncompCert.pData)
  1102. {
  1103. GMEM_Free(TryUncompCert.pData);
  1104. TryUncompCert.pData = NULL_PTR;
  1105. }
  1106. /* Allocation de la m�moire pour le certificat */
  1107. if (pCompCert->usLen < pCert->usLen + 1)
  1108. {
  1109. pCompCert->usLen = pCert->usLen + 1;
  1110. if (pCompCert->pData)
  1111. {
  1112. return(RV_BUFFER_TOO_SMALL);
  1113. }
  1114. else
  1115. {
  1116. return(RV_SUCCESS);
  1117. }
  1118. }
  1119. pCompCert->usLen = pCert->usLen + 1;
  1120. pCompCert->pData[0] = TAG_COMPRESSION_FAILED;
  1121. if (pCompCert->pData)
  1122. {
  1123. memcpy(&pCompCert->pData[1], pCert->pData, pCert->usLen);
  1124. }
  1125. return(RV_COMPRESSION_FAILED);
  1126. }
  1127. #ifdef _STUDY
  1128. fseek(pfdBinAc256, 0, SEEK_SET);
  1129. fwrite(Ac256, sizeof(int), 256, pfdBinAc256);
  1130. fseek(pfdBinAc16, 0, SEEK_SET);
  1131. fwrite(Ac16, sizeof(int), 16, pfdBinAc16);
  1132. fseek(pfdBinAc4, 0, SEEK_SET);
  1133. fwrite(Ac4, sizeof(int), 4, pfdBinAc4);
  1134. fseek(pfdBinAc2, 0, SEEK_SET);
  1135. fwrite(Ac2, sizeof(int), 2, pfdBinAc2);
  1136. if ((pfdLogFreq = fopen("Freq.log", "w")) == 0)
  1137. {
  1138. return(RV_FILE_OPEN_FAILED);
  1139. }
  1140. for (sum = 0, i = 0; i < 256; sum += Ac256[i], i++) ;
  1141. fprintf(pfdLogFreq, "\nTotal = %d\n\n", sum * 8);
  1142. for (i = 0; i < 2; i++)
  1143. {
  1144. fprintf(pfdLogFreq, "0x%02X (%03d) '%c' : %8d - %04.2f %%\n",
  1145. i, i, (isgraph(i) ? i : ' '),
  1146. Ac2[i], ((float) 100 * Ac2[i] / (sum * 8)));
  1147. }
  1148. fprintf(pfdLogFreq, "\nTotal = %d\n\n", sum * 4);
  1149. for (i = 0; i < 4; i++)
  1150. {
  1151. fprintf(pfdLogFreq, "0x%02X (%03d) '%c' : %8d - %04.2f %%\n",
  1152. i, i, (isgraph(i) ? i : ' '),
  1153. Ac4[i], ((float) 100 * Ac4[i] / (sum * 4)));
  1154. }
  1155. fprintf(pfdLogFreq, "\nTotal = %d\n\n", sum * 2);
  1156. for (i = 0; i < 16; i++)
  1157. {
  1158. fprintf(pfdLogFreq, "0x%02X (%03d) '%c' : %8d - %04.2f %%\n",
  1159. i, i, (isgraph(i) ? i : ' '),
  1160. Ac16[i], ((float) 100 * Ac16[i] / (sum * 2)));
  1161. }
  1162. fprintf(pfdLogFreq, "\nTotal = %d\n\n", sum);
  1163. for (i = 0; i < 256; i++)
  1164. {
  1165. fprintf(pfdLogFreq, "0x%02X (%03d) '%c' : %8d - %04.2f %%\n",
  1166. i, i, (isgraph(i) ? i : ' '),
  1167. Ac256[i], ((float) 100 * Ac256[i] / sum));
  1168. }
  1169. fclose(pfdBinAc256);
  1170. fclose(pfdBinAc16);
  1171. fclose(pfdBinAc4);
  1172. fclose(pfdBinAc2);
  1173. fclose(pfdLogFreq);
  1174. fclose(pfdLog);
  1175. #endif
  1176. /* Si tout s'est bien pass�, on renvoie le r�sultat en indiquant
  1177. qu'il est compress (DictVersion != 0xFF) */
  1178. /* Allocation de la m�moire pour le certificat */
  1179. if (pCompCert->usLen < TryCompCert.usLen + 1)
  1180. {
  1181. if (TryCompCert.pData)
  1182. {
  1183. GMEM_Free(TryCompCert.pData);
  1184. TryCompCert.pData = NULL_PTR;
  1185. }
  1186. if (TryUncompCert.pData)
  1187. {
  1188. GMEM_Free(TryUncompCert.pData);
  1189. TryUncompCert.pData = NULL_PTR;
  1190. }
  1191. pCompCert->usLen = TryCompCert.usLen + 1;
  1192. if (pCompCert->pData)
  1193. {
  1194. return(RV_BUFFER_TOO_SMALL);
  1195. }
  1196. else
  1197. {
  1198. return(RV_SUCCESS);
  1199. }
  1200. }
  1201. pCompCert->usLen = TryCompCert.usLen + 1;
  1202. if (pCompCert->pData)
  1203. {
  1204. pCompCert->pData[0] = DictVersion;
  1205. memcpy(&pCompCert->pData[1], TryCompCert.pData, TryCompCert.usLen);
  1206. }
  1207. if (TryCompCert.pData)
  1208. {
  1209. GMEM_Free(TryCompCert.pData);
  1210. TryCompCert.pData = NULL_PTR;
  1211. }
  1212. if (TryUncompCert.pData)
  1213. {
  1214. GMEM_Free(TryUncompCert.pData);
  1215. TryUncompCert.pData = NULL_PTR;
  1216. }
  1217. if (pCert->usLen != TryUncompCert.usLen)
  1218. {
  1219. return(RV_BLOC_TOO_LONG);
  1220. }
  1221. return(RV_SUCCESS);
  1222. }
  1223. /*******************************************************************************
  1224. * int CC_Uncompress(BLOC *pCompCert,
  1225. * BLOC *pUncompCert
  1226. * )
  1227. *
  1228. * Description : Fonction de mta-dcompression visible depuis l'extrieur.
  1229. * Retourne le bloc original (entre de la fonction CC_Compress)
  1230. * sous rserve toutefois d'une version adquate du dictionnaire.
  1231. *
  1232. * Remarks : Le champ pData du bloc d'entre a t allou par la fonction appelant.
  1233. * Le champ pData du bloc de sortie est allou ici. Il doit tre
  1234. * dsallou par la fonction appelant (sauf si erreur).
  1235. * Le comportement est imprvisible dans le cas o le bloc d'entre
  1236. * n'est pas le bloc de sortie d'un appel la fonction CC_Compress.
  1237. *
  1238. * In : *pCompCert : Bloc mta-dcompresser
  1239. *
  1240. * Out : *pUncompCert : Bloc 'mta-dcompress'
  1241. * (ou vide si RV_BAD_DICTIONARY)
  1242. *
  1243. * Responses : RV_SUCCESS : All is OK.
  1244. * RV_BAD_DICTIONARY : La version du dictionnaire utilise pour la
  1245. * dcompression est plus ancienne que celle
  1246. * utilise pour la compression.
  1247. * RV_MALLOC_FAILED : Un malloc a chou.
  1248. * Autre : D'autres codes d'erreur peuvent tre retourns lors de
  1249. * la dcompression.
  1250. *
  1251. *******************************************************************************/
  1252. int CC_Uncompress(BLOC *pCompCert,
  1253. BLOC *pUncompCert
  1254. )
  1255. {
  1256. int
  1257. resp;
  1258. BLOC
  1259. TempCompCert,
  1260. TempUncompCert;
  1261. if (pCompCert->pData[0] == TAG_COMPRESSION_FAILED)
  1262. {
  1263. /* Allocation de la m�moire pour le certificat
  1264. On pourrait se contenter de ne retourner que la zone mmoire
  1265. partir de l'octet 1 mais la fonction de dcompression est sense
  1266. toujours allouer la zone dans laquelle elle renvoie le dcompress */
  1267. if(pUncompCert->usLen < pCompCert->usLen - 1)
  1268. {
  1269. pUncompCert->usLen = pCompCert->usLen - 1;
  1270. if (pUncompCert->pData)
  1271. {
  1272. return(RV_BUFFER_TOO_SMALL);
  1273. }
  1274. else
  1275. {
  1276. return(RV_SUCCESS);
  1277. }
  1278. }
  1279. pUncompCert->usLen = pCompCert->usLen - 1;
  1280. if (pUncompCert->pData)
  1281. {
  1282. memcpy(pUncompCert->pData, &pCompCert->pData[1], pUncompCert->usLen);
  1283. }
  1284. return (RV_SUCCESS);
  1285. }
  1286. else if (pCompCert->pData[0] <= DictVersion)
  1287. {
  1288. TempCompCert.pData = &pCompCert->pData[1];
  1289. TempCompCert.usLen = pCompCert->usLen - 1;
  1290. TempUncompCert.usLen = 0;
  1291. resp = CC_Uncomp(&TempCompCert, &TempUncompCert);
  1292. if (resp == RV_SUCCESS)
  1293. {
  1294. if(pUncompCert->usLen < TempUncompCert.usLen)
  1295. {
  1296. GMEM_Free(TempUncompCert.pData);
  1297. pUncompCert->usLen = TempUncompCert.usLen;
  1298. if (pUncompCert->pData)
  1299. {
  1300. return(RV_BUFFER_TOO_SMALL);
  1301. }
  1302. else
  1303. {
  1304. return(RV_SUCCESS);
  1305. }
  1306. }
  1307. pUncompCert->usLen = TempUncompCert.usLen;
  1308. if (pUncompCert->pData)
  1309. {
  1310. memcpy(pUncompCert->pData, TempUncompCert.pData, TempUncompCert.usLen);
  1311. }
  1312. GMEM_Free(TempUncompCert.pData);
  1313. }
  1314. return (resp);
  1315. }
  1316. else
  1317. {
  1318. return (RV_BAD_DICTIONARY);
  1319. }
  1320. }
  1321. /*******************************************************************************
  1322. * int CC_Comp(BLOC *pCertificate,
  1323. * BLOC *pCompressedCertificate
  1324. * )
  1325. *
  1326. * Description : Fonction interne de compression d'un certificat.
  1327. *
  1328. * Remarks : Le champ pData du bloc d'entre a t allou par la fonction appelant.
  1329. * Le champ pData du bloc de sortie est allou ici. Il doit tre
  1330. * dsallou par la fonction appelant (sauf si erreur).
  1331. *
  1332. * In : *pCertificate : Bloc compresser
  1333. *
  1334. * Out : *pCompressedCertificate : Bloc compress
  1335. *
  1336. * Responses : RV_SUCCESS : All is OK.
  1337. * RV_MALLOC_FAILED : Un malloc a chou.
  1338. * Autre : D'autres codes d'erreur peuvent tre retourns par des
  1339. * fonctions d'un niveau infrieur.
  1340. *
  1341. *******************************************************************************/
  1342. int CC_Comp(BLOC *pCertificate,
  1343. BLOC *pCompressedCertificate
  1344. )
  1345. {
  1346. ASN1
  1347. Cert,
  1348. tbsCert,
  1349. signatureAlgo,
  1350. signature;
  1351. BLOC
  1352. TmpCompCert,
  1353. tbsCertEncoded,
  1354. signatureAlgoEncoded,
  1355. signatureEncoded;
  1356. BYTE
  1357. *pCurrent;
  1358. int
  1359. rv;
  1360. /* Eclatement du certificat en ses trois composants principaux */
  1361. dwPtrMax = pCertificate->pData + pCertificate->usLen;
  1362. Cert.Asn1.pData = pCertificate->pData;
  1363. rv = CC_ExtractContent(&Cert);
  1364. if (rv != RV_SUCCESS) return rv;
  1365. if (Cert.Asn1.usLen != pCertificate->usLen)
  1366. {
  1367. return(RV_INVALID_DATA);
  1368. }
  1369. tbsCert.Asn1.pData = Cert.Content.pData;
  1370. rv = CC_ExtractContent(&tbsCert);
  1371. if (rv != RV_SUCCESS) return rv;
  1372. signatureAlgo.Asn1.pData = tbsCert.Content.pData + tbsCert.Content.usLen;
  1373. rv = CC_ExtractContent(&signatureAlgo);
  1374. if (rv != RV_SUCCESS) return rv;
  1375. signature.Asn1.pData = signatureAlgo.Content.pData + signatureAlgo.Content.usLen;
  1376. rv = CC_ExtractContent(&signature);
  1377. if (rv != RV_SUCCESS) return rv;
  1378. ASSERT(signature.Content.pData + signature.Content.usLen ==
  1379. Cert.Content.pData + Cert.Content.usLen);
  1380. /* Elaboration des composants principaux compress�s */
  1381. /* Les pData des blocs *Encoded sont allou�s par les fonctions CC_Encode_*.
  1382. Ils sont librs dans cette fonction aprs usage */
  1383. tbsCertEncoded.pData = NULL;
  1384. signatureAlgoEncoded.pData = NULL;
  1385. signatureEncoded.pData = NULL;
  1386. rv = CC_Encode_TBSCertificate(&tbsCert.Content, &tbsCertEncoded);
  1387. if (rv != RV_SUCCESS) goto err;
  1388. rv = CC_Encode_AlgorithmIdentifier(&signatureAlgo.Content, &signatureAlgoEncoded);
  1389. if (rv != RV_SUCCESS) goto err;
  1390. rv = CC_Encode_Signature(&signature.Content, &signatureEncoded);
  1391. if (rv != RV_SUCCESS) goto err;
  1392. /* Reconstruction du certificat compress� � partir de ses composants */
  1393. TmpCompCert.usLen = tbsCertEncoded.usLen
  1394. + signatureAlgoEncoded.usLen
  1395. + signatureEncoded.usLen;
  1396. /* A d�sallouer par le programme appelant */
  1397. if ((TmpCompCert.pData = GMEM_Alloc(TmpCompCert.usLen)) == NULL_PTR)
  1398. {
  1399. rv = RV_MALLOC_FAILED;
  1400. goto err;
  1401. }
  1402. pCurrent = TmpCompCert.pData;
  1403. memcpy(pCurrent, tbsCertEncoded.pData, tbsCertEncoded.usLen);
  1404. GMEM_Free(tbsCertEncoded.pData);
  1405. pCurrent += tbsCertEncoded.usLen;
  1406. memcpy(pCurrent, signatureAlgoEncoded.pData, signatureAlgoEncoded.usLen);
  1407. GMEM_Free(signatureAlgoEncoded.pData);
  1408. pCurrent += signatureAlgoEncoded.usLen;
  1409. memcpy(pCurrent, signatureEncoded.pData, signatureEncoded.usLen);
  1410. GMEM_Free(signatureEncoded.pData);
  1411. pCurrent += signatureEncoded.usLen;
  1412. /* Et maintenant on compresse le certificat compress� !! */
  1413. #ifdef _GLOBAL_COMPRESSION
  1414. rv = CC_RawEncode(&TmpCompCert, pCompressedCertificate, FALSE);
  1415. GMEM_Free(TmpCompCert.pData);
  1416. if (rv != RV_SUCCESS) goto err;
  1417. #else
  1418. *pCompressedCertificate = TmpCompCert;
  1419. #endif
  1420. return(RV_SUCCESS);
  1421. err:
  1422. GMEM_Free(tbsCertEncoded.pData);
  1423. GMEM_Free(signatureAlgoEncoded.pData);
  1424. GMEM_Free(signatureEncoded.pData);
  1425. return (rv);
  1426. }
  1427. /*******************************************************************************
  1428. * int CC_Uncomp(BLOC *pCompressedCertificate,
  1429. * BLOC *pUncompressedCertificate
  1430. * )
  1431. *
  1432. * Description : Fonction interne de dcompression d'un certificat.
  1433. *
  1434. * Remarks : Le champ pData du bloc d'entre a t allou par la fonction appelant.
  1435. * Le champ pData du bloc de sortie est allou ici. Il doit tre
  1436. * dsallou par la fonction appelant (sauf si erreur).
  1437. *
  1438. * In : *pCertificate : Bloc compresser
  1439. *
  1440. * Out : *pCompressedCertificate : Bloc compress
  1441. *
  1442. * Responses : RV_SUCCESS : All is OK.
  1443. * RV_MALLOC_FAILED : Un malloc a chou.
  1444. * Autre : D'autres codes d'erreur peuvent tre retourns par des
  1445. * fonctions d'un niveau infrieur.
  1446. *
  1447. *******************************************************************************/
  1448. int CC_Uncomp(BLOC *pCompressedCertificate,
  1449. BLOC *pUncompressedCertificate
  1450. )
  1451. {
  1452. ASN1
  1453. Cert,
  1454. tbsCert,
  1455. signatureAlgo,
  1456. signature;
  1457. BLOC
  1458. TmpCompCert;
  1459. BYTE
  1460. *pCurrent;
  1461. int
  1462. rv;
  1463. USHORT
  1464. Length;
  1465. tbsCert.Asn1.pData = NULL;
  1466. signatureAlgo.Asn1.pData = NULL;
  1467. signature.Asn1.pData = NULL;
  1468. #ifdef _GLOBAL_COMPRESSION
  1469. /* Length est ici inutile */
  1470. rv = CC_RawDecode(pCompressedCertificate->pData, &TmpCompCert, &Length, FALSE);
  1471. if (rv != RV_SUCCESS) return rv;
  1472. #else
  1473. TmpCompCert = *pCompressedCertificate;
  1474. #endif
  1475. /* D�codage des diff�rents composants du certificat */
  1476. /* CC_Decode_* et cc_BuildAsn1 allouent les pData de leurs arguments de
  1477. sortie. Ces zones sont dsallouer ce niveau aprs usage. */
  1478. pCurrent = TmpCompCert.pData;
  1479. rv = CC_Decode_TBSCertificate(pCurrent, &tbsCert.Content, &Length);
  1480. if (rv != RV_SUCCESS) goto err;
  1481. tbsCert.Tag = TAG_SEQUENCE;
  1482. rv = CC_BuildAsn1(&tbsCert);
  1483. GMEM_Free(tbsCert.Content.pData);
  1484. if (rv != RV_SUCCESS) goto err;
  1485. pCurrent += Length;
  1486. rv = CC_Decode_AlgorithmIdentifier(pCurrent, &signatureAlgo.Content, &Length);
  1487. if (rv != RV_SUCCESS) goto err;
  1488. signatureAlgo.Tag = TAG_SEQUENCE;
  1489. rv = CC_BuildAsn1(&signatureAlgo);
  1490. GMEM_Free(signatureAlgo.Content.pData);
  1491. if (rv != RV_SUCCESS) goto err;
  1492. pCurrent += Length;
  1493. rv = CC_Decode_Signature(pCurrent, &signature.Content, &Length);
  1494. if (rv != RV_SUCCESS) goto err;
  1495. signature.Tag = TAG_BIT_STRING;
  1496. rv = CC_BuildAsn1(&signature);
  1497. GMEM_Free(signature.Content.pData);
  1498. if (rv != RV_SUCCESS) goto err;
  1499. pCurrent += Length;
  1500. ASSERT(pCurrent == TmpCompCert.pData + TmpCompCert.usLen);
  1501. #ifdef _GLOBAL_COMPRESSION
  1502. GMEM_Free(TmpCompCert.pData);
  1503. #endif
  1504. /* Reconstruction de l'enveloppe Asn1 du certificat */
  1505. /* A d�sallouer � ce niveau apr�s usage */
  1506. Cert.Content.usLen = tbsCert.Asn1.usLen
  1507. + signatureAlgo.Asn1.usLen
  1508. + signature.Asn1.usLen;
  1509. if ((Cert.Content.pData = GMEM_Alloc(Cert.Content.usLen)) == NULL_PTR)
  1510. {
  1511. rv = RV_MALLOC_FAILED;
  1512. goto err;
  1513. }
  1514. pCurrent = Cert.Content.pData;
  1515. memcpy(pCurrent, tbsCert.Asn1.pData, tbsCert.Asn1.usLen);
  1516. GMEM_Free(tbsCert.Asn1.pData);
  1517. pCurrent += tbsCert.Asn1.usLen;
  1518. memcpy(pCurrent, signatureAlgo.Asn1.pData, signatureAlgo.Asn1.usLen);
  1519. GMEM_Free(signatureAlgo.Asn1.pData);
  1520. pCurrent += signatureAlgo.Asn1.usLen;
  1521. memcpy(pCurrent, signature.Asn1.pData, signature.Asn1.usLen);
  1522. GMEM_Free(signature.Asn1.pData);
  1523. pCurrent += signature.Asn1.usLen;
  1524. Cert.Tag = TAG_SEQUENCE;
  1525. rv = CC_BuildAsn1(&Cert);
  1526. GMEM_Free(Cert.Content.pData);
  1527. if (rv != RV_SUCCESS) return rv;
  1528. *pUncompressedCertificate = Cert.Asn1;
  1529. return(RV_SUCCESS);
  1530. err:
  1531. GMEM_Free(tbsCert.Asn1.pData);
  1532. GMEM_Free(signatureAlgo.Asn1.pData);
  1533. GMEM_Free(signature.Asn1.pData);
  1534. return(rv);
  1535. }
  1536. /*******************************************************************************
  1537. * int CC_ExtractContent(ASN1 *pAsn1)
  1538. *
  1539. * Description : Extrait d'un bloc Asn1 (pAsn1->Asn1) son contenu en laguant son
  1540. * enrobage (identifier bytes, length bytes) et le place dans le
  1541. * bloc pAsn1->Content.
  1542. *
  1543. * Remarks : Le champ Asn1.pData a t allou par la fonction appelant.
  1544. *
  1545. * In : pAsn1->Asn1.pData
  1546. *
  1547. * Out : Les champs suivants sont renseigns (si RV_SUCCESS) :
  1548. * - Tag
  1549. * - Asn1.usLen
  1550. * - Content.usLen
  1551. * - Content.pData (pas d'allocation : on fait pointer sur la partie
  1552. * adquate du contenu de Asn1.pData)
  1553. *
  1554. * Responses : RV_SUCCESS : All is OK.
  1555. * RV_INVALID_DATA : Le format du bloc Asn1 n'est pas support.
  1556. *
  1557. *******************************************************************************/
  1558. int CC_ExtractContent(ASN1 *pAsn1)
  1559. {
  1560. BYTE
  1561. *pData;
  1562. int
  1563. NbBytes,
  1564. i;
  1565. pData = pAsn1->Asn1.pData;
  1566. if ((pData[0] & 0x1F) == 0x1F)
  1567. {
  1568. /* High-tag-number : non support� */
  1569. return(RV_INVALID_DATA);
  1570. }
  1571. else
  1572. {
  1573. pAsn1->Tag = pData[0];
  1574. }
  1575. if (pData[1] == 0x80)
  1576. {
  1577. /* Constructed, indefinite-length method : non support� */
  1578. return(RV_INVALID_DATA);
  1579. }
  1580. else if (pData[1] > 0x82)
  1581. {
  1582. /* Constructed, definite-length method : longueur trop grande */
  1583. return(RV_INVALID_DATA);
  1584. }
  1585. else if (pData[1] < 0x80)
  1586. {
  1587. /* Primitive, definite-length method */
  1588. pAsn1->Content.usLen = pData[1];
  1589. pAsn1->Content.pData = &pData[2];
  1590. pAsn1->Asn1.usLen = pAsn1->Content.usLen + 2;
  1591. /* Looking for memory violation */
  1592. if (pData + pAsn1->Content.usLen + 2 > dwPtrMax)
  1593. {
  1594. return(RV_INVALID_DATA);
  1595. }
  1596. }
  1597. else
  1598. {
  1599. /* Constructed, definite-length method */
  1600. NbBytes = pData[1] & 0x7F;
  1601. ASSERT(NbBytes <= 2);
  1602. pAsn1->Content.usLen = 0;
  1603. for (i = 0; i < NbBytes; i++)
  1604. {
  1605. pAsn1->Content.usLen = (pAsn1->Content.usLen << 8) + pData[2+i];
  1606. }
  1607. /* Looking for memory violation */
  1608. if (pData + pAsn1->Content.usLen+2+NbBytes > dwPtrMax)
  1609. {
  1610. return(RV_INVALID_DATA);
  1611. }
  1612. pAsn1->Content.pData = &pData[2+NbBytes];
  1613. pAsn1->Asn1.usLen = pAsn1->Content.usLen + 2 + NbBytes;
  1614. }
  1615. return(RV_SUCCESS);
  1616. }
  1617. /*******************************************************************************
  1618. * int CC_BuildAsn1(ASN1 *pAsn1)
  1619. *
  1620. * Description : Reconstruit un bloc Asn1 (pAsn1->Asn1) partir de son contenu
  1621. * (pAsn1->Content) et de son Tag suppos spcifi (pAsn1->Tag)
  1622. * en synthtisant son enrobage (identifier bytes, length bytes).
  1623. *
  1624. * Remarks : Le champ Content.pData a t allou par la fonction appelant.
  1625. * Seulement la forme 'low-tag-number' (tag sur un seul octet) est
  1626. * supporte.
  1627. *
  1628. * In : pAsn1->Content.usLen
  1629. * pAsn1->Content.pData
  1630. * pAsn1->Tag
  1631. *
  1632. * Out : Les champs suivants sont renseigns (si RV_SUCCESS) :
  1633. * - Asn1.usLen
  1634. * - Asn1.pData (allou ici, librer par la fonction appelant)
  1635. *
  1636. * Responses : RV_SUCCESS : All is OK.
  1637. * RV_MALLOC_FAILED : Un malloc a chou.
  1638. *
  1639. *******************************************************************************/
  1640. int CC_BuildAsn1(ASN1 *pAsn1)
  1641. {
  1642. if (pAsn1->Content.usLen < 0x0080)
  1643. {
  1644. pAsn1->Asn1.usLen = pAsn1->Content.usLen + 2;
  1645. if ((pAsn1->Asn1.pData = GMEM_Alloc(pAsn1->Asn1.usLen)) == NULL_PTR)
  1646. {
  1647. return(RV_MALLOC_FAILED);
  1648. }
  1649. pAsn1->Asn1.pData[0] = (BYTE) pAsn1->Tag;
  1650. pAsn1->Asn1.pData[1] = (BYTE) pAsn1->Content.usLen;
  1651. memcpy(&(pAsn1->Asn1.pData[2]), pAsn1->Content.pData, pAsn1->Content.usLen);
  1652. }
  1653. else
  1654. {
  1655. if (pAsn1->Content.usLen < 0x0100)
  1656. {
  1657. pAsn1->Asn1.usLen = pAsn1->Content.usLen + 3;
  1658. if ((pAsn1->Asn1.pData = GMEM_Alloc(pAsn1->Asn1.usLen)) == NULL_PTR)
  1659. {
  1660. return(RV_MALLOC_FAILED);
  1661. }
  1662. pAsn1->Asn1.pData[0] = pAsn1->Tag;
  1663. pAsn1->Asn1.pData[1] = 0x81;
  1664. pAsn1->Asn1.pData[2] = (BYTE)pAsn1->Content.usLen;
  1665. memcpy(&(pAsn1->Asn1.pData[3]), pAsn1->Content.pData, pAsn1->Content.usLen);
  1666. }
  1667. else
  1668. {
  1669. pAsn1->Asn1.usLen = pAsn1->Content.usLen + 4;
  1670. if ((pAsn1->Asn1.pData = GMEM_Alloc(pAsn1->Asn1.usLen)) == NULL_PTR)
  1671. {
  1672. return(RV_MALLOC_FAILED);
  1673. }
  1674. pAsn1->Asn1.pData[0] = pAsn1->Tag;
  1675. pAsn1->Asn1.pData[1] = 0x82;
  1676. pAsn1->Asn1.pData[2] = pAsn1->Content.usLen >> 8;
  1677. pAsn1->Asn1.pData[3] = pAsn1->Content.usLen & 0x00FF;
  1678. memcpy(&(pAsn1->Asn1.pData[4]), pAsn1->Content.pData, pAsn1->Content.usLen);
  1679. }
  1680. }
  1681. return(RV_SUCCESS);
  1682. }
  1683. /*******************************************************************************
  1684. * int SearchDataByIndex(USHORT usIndex,
  1685. * BYTE *pDict,
  1686. * BLOC *pOutBloc
  1687. * )
  1688. *
  1689. * Description : Recherche l'entre (mot/phrase) dans le dictionnaire dont
  1690. * l'index est spcifi en entre.
  1691. *
  1692. * Remarks : Le format du dictionnaire est le suivant :
  1693. *
  1694. * - 2 octets : le nombre d'entres
  1695. * - 2 octets : la longueur totale du dictionnaire
  1696. *
  1697. * - 2 octets : I0, l'index de l'entre 0
  1698. * - 2 octets : L0, la longueur de l'entre 0
  1699. * - L0 octets : l'entre 0
  1700. *
  1701. * - 2 octets : I1, l'index de l'entre 1
  1702. * - 2 octets : L1, la longueur de l'entre 1
  1703. * - L1 octets : l'entre 1
  1704. *
  1705. * - ........
  1706. *
  1707. * In : usIndex : l'index du mot/phrase recherch
  1708. * pDict : pointe sur le dictionnaire charg en mmoire
  1709. *
  1710. * Out : pOutBloc : l'entre correspondant l'index
  1711. *
  1712. * Responses : RV_SUCCESS : All is OK.
  1713. * RV_BAD_DICTIONARY : Aucune entre ayant le bon index n'a t
  1714. * trouve dans le dictionnaire.
  1715. *
  1716. *******************************************************************************/
  1717. int SearchDataByIndex(USHORT usIndex,
  1718. BYTE *pDict,
  1719. BLOC *pOutBloc
  1720. )
  1721. {
  1722. BYTE
  1723. *pCurrent;
  1724. BOOL
  1725. bFound = FALSE;
  1726. USHORT
  1727. i,
  1728. usLength,
  1729. usCount,
  1730. usCurrent;
  1731. usCount = *(USHORT *)pDict; //memcpy(&usCount, pDict, sizeof(usCount));
  1732. pCurrent = pDict + 4;
  1733. bFound = FALSE;
  1734. for (i = 0; i < usCount; i++)
  1735. {
  1736. usCurrent = *(USHORT UNALIGNED *)pCurrent; //memcpy(&usCurrent, (USHORT *) pCurrent, 2);
  1737. pCurrent += 2;
  1738. if (usCurrent == usIndex)
  1739. {
  1740. bFound = TRUE;
  1741. break;
  1742. }
  1743. usLength = *(USHORT UNALIGNED *)pCurrent; //memcpy(&usLength, (USHORT *) pCurrent, 2);
  1744. pCurrent += (2 + usLength);
  1745. }
  1746. if (!bFound)
  1747. {
  1748. return(RV_BAD_DICTIONARY);
  1749. }
  1750. usLength = *(USHORT UNALIGNED *)pCurrent; //memcpy(&usLength, (USHORT *) pCurrent, 2);
  1751. pCurrent += 2;
  1752. pOutBloc->pData = pCurrent;
  1753. pOutBloc->usLen = usLength;
  1754. return(RV_SUCCESS);
  1755. }
  1756. /*******************************************************************************
  1757. * int CC_RawEncode(BLOC *pInBloc,
  1758. * BLOC *pOutBloc,
  1759. * BOOL bUseDictionary
  1760. * )
  1761. *
  1762. * Description : Traite le bloc d'entre comme une donne terminale dans le
  1763. * processus d'extractions successives des enrobages Asn1.
  1764. * Le but est ici de compresser au maximum ce bloc sans faire
  1765. * aucune hypothse sur sa structure Asn1. Pour ce faire, on
  1766. * commence (si bUseDictionary == TRUE) par remplacer chaque
  1767. * mot/phrase du dictionnaire rencontr par son index prcd d'un
  1768. * caractre d'chappement, puis on applique la donne rsiduelle
  1769. * successivement chaque algorithme de compression statistique pour
  1770. * n'en retenir que le meilleur. La sortie est le meilleur
  1771. * compress du rsidu prcd d'un header codant le numro de
  1772. * l'algo ainsi que la longueur du compress.
  1773. *
  1774. * Remarks :
  1775. *
  1776. * In : pInBloc : le bloc encoder
  1777. * bUseDictionary : on peut ne pas utiliser le dictionnaire
  1778. *
  1779. * Out : pOutBloc : le bloc encod (mmoire alloue ici librer par le
  1780. * programme appelant)
  1781. *
  1782. * Responses : RV_SUCCESS : All is OK.
  1783. * RV_MALLOC_FAILED : Un malloc a chou.
  1784. * RV_INVALID_DATA : Le meilleur compress du rsidu est trop long.
  1785. * Autre : D'autres codes d'erreur peuvent tre retourns par des
  1786. * fonctions d'un niveau infrieur.
  1787. *
  1788. *******************************************************************************/
  1789. int CC_RawEncode(BLOC *pInBloc,
  1790. BLOC *pOutBloc,
  1791. BOOL bUseDictionary
  1792. )
  1793. {
  1794. BLOC
  1795. OldBloc,
  1796. NewBloc,
  1797. CompBloc,
  1798. BestBloc;
  1799. BOOL
  1800. bFound;
  1801. BYTE
  1802. *pCurrent,
  1803. *pToCurrent,
  1804. *pFromCurrent,
  1805. *pData,
  1806. BestAlgoId;
  1807. int
  1808. // value,
  1809. rv;
  1810. USHORT
  1811. pos,
  1812. usEscapeCount,
  1813. usIndex,
  1814. usLength,
  1815. usCount,
  1816. usCurrent;
  1817. /* Il peut �tre int�ressant de ne pas utiliser le dictionnaire si on sait
  1818. qu'il ne va pas servir car cela evite de doubler les 0xFF pour rien */
  1819. if (bUseDictionary == FALSE)
  1820. {
  1821. OldBloc.usLen = pInBloc->usLen;
  1822. if ((OldBloc.pData = GMEM_Alloc(OldBloc.usLen)) == NULL_PTR)
  1823. {
  1824. return(RV_MALLOC_FAILED);
  1825. }
  1826. memcpy(OldBloc.pData, pInBloc->pData, OldBloc.usLen);
  1827. }
  1828. else
  1829. {
  1830. /* On recopie le bloc d'entr�e dans un bloc de travail en doublant les 'escape' */
  1831. pCurrent = pInBloc->pData;
  1832. usEscapeCount = 0;
  1833. for (pos = 0; pos < pInBloc->usLen; pos++)
  1834. {
  1835. if (*pCurrent == ESCAPE_CHAR)
  1836. {
  1837. usEscapeCount++;
  1838. }
  1839. pCurrent++;
  1840. }
  1841. OldBloc.usLen = pInBloc->usLen + usEscapeCount;
  1842. if ((OldBloc.pData = GMEM_Alloc(OldBloc.usLen)) == NULL_PTR)
  1843. {
  1844. return(RV_MALLOC_FAILED);
  1845. }
  1846. pFromCurrent = pInBloc->pData;
  1847. pToCurrent = OldBloc.pData;
  1848. for (pos = 0; pos < pInBloc->usLen; pos++)
  1849. {
  1850. if ((*pToCurrent = *pFromCurrent) == ESCAPE_CHAR)
  1851. {
  1852. pToCurrent++;
  1853. *pToCurrent = ESCAPE_CHAR;
  1854. }
  1855. pFromCurrent++;
  1856. pToCurrent++;
  1857. }
  1858. /* Si un dictionnaire existe, on l'utilise pour coder ses entr�es rencontr�es */
  1859. if (pDictMemory != NULL_PTR)
  1860. {
  1861. pCurrent = pDictMemory;
  1862. memcpy(&usCount, pCurrent, sizeof(usCount));
  1863. pCurrent += 4;
  1864. for (usCurrent = 0; usCurrent < usCount; usCurrent++)
  1865. {
  1866. memcpy(&usIndex, pCurrent, sizeof(usIndex));
  1867. pCurrent += 2;
  1868. memcpy(&usLength, pCurrent, sizeof(usLength));
  1869. pCurrent += 2;
  1870. if (usLength <= OldBloc.usLen)
  1871. {
  1872. bFound = FALSE;
  1873. for (pos = 0; pos < OldBloc.usLen - usLength + 1; pos++)
  1874. {
  1875. if (memcmp(pCurrent, OldBloc.pData + pos, usLength) == 0)
  1876. {
  1877. bFound = TRUE;
  1878. break;
  1879. }
  1880. }
  1881. if (bFound)
  1882. {
  1883. if (usIndex < 0x80)
  1884. {
  1885. NewBloc.usLen = OldBloc.usLen - usLength + 2;
  1886. if ((NewBloc.pData = GMEM_Alloc(NewBloc.usLen)) == NULL_PTR)
  1887. {
  1888. GMEM_Free(OldBloc.pData);
  1889. return(RV_MALLOC_FAILED);
  1890. }
  1891. memcpy(NewBloc.pData, OldBloc.pData, pos);
  1892. NewBloc.pData[pos] = ESCAPE_CHAR;
  1893. NewBloc.pData[pos + 1] = (BYTE) usIndex;
  1894. memcpy(NewBloc.pData + pos + 2,
  1895. OldBloc.pData + pos + usLength,
  1896. OldBloc.usLen - pos - usLength);
  1897. GMEM_Free(OldBloc.pData);
  1898. }
  1899. else
  1900. {
  1901. NewBloc.usLen = OldBloc.usLen - usLength + 3;
  1902. if ((NewBloc.pData = GMEM_Alloc(NewBloc.usLen)) == NULL_PTR)
  1903. {
  1904. GMEM_Free(OldBloc.pData);
  1905. return(RV_MALLOC_FAILED);
  1906. }
  1907. memcpy(NewBloc.pData, OldBloc.pData, pos);
  1908. NewBloc.pData[pos] = ESCAPE_CHAR;
  1909. NewBloc.pData[pos + 1] = (BYTE) (usIndex >> 8) | 0x80;
  1910. NewBloc.pData[pos + 2] = (BYTE) (usIndex & 0x00FF);
  1911. memcpy(NewBloc.pData + pos + 3,
  1912. OldBloc.pData + pos + usLength,
  1913. OldBloc.usLen - pos - usLength);
  1914. GMEM_Free(OldBloc.pData);
  1915. }
  1916. OldBloc = NewBloc;
  1917. }
  1918. }
  1919. pCurrent += usLength;
  1920. }
  1921. }
  1922. }
  1923. #ifdef _STUDY
  1924. for (i = 0; i < OldBloc.usLen; i++)
  1925. {
  1926. value = OldBloc.pData[i];
  1927. Ac256[value]++;
  1928. Ac16[value & 0x0F]++;
  1929. Ac16[(value & 0xF0) >> 4]++;
  1930. Ac4[value & 0x03]++;
  1931. Ac4[(value & 0x0C) >> 2]++;
  1932. Ac4[(value & 0x30) >> 4]++;
  1933. Ac4[(value & 0xC0) >> 6]++;
  1934. Ac2[value & 0x01]++; value >>= 1;
  1935. Ac2[value & 0x01]++; value >>= 1;
  1936. Ac2[value & 0x01]++; value >>= 1;
  1937. Ac2[value & 0x01]++; value >>= 1;
  1938. Ac2[value & 0x01]++; value >>= 1;
  1939. Ac2[value & 0x01]++; value >>= 1;
  1940. Ac2[value & 0x01]++; value >>= 1;
  1941. Ac2[value & 0x01]++; value >>= 1;
  1942. }
  1943. fprintf(pfdLog, "\n");
  1944. for (i = 0; i < (OldBloc.usLen <= 8 ? OldBloc.usLen : 8); i++)
  1945. {
  1946. fprintf(pfdLog, "%02X", OldBloc.pData[i]);
  1947. }
  1948. fprintf(pfdLog, " (");
  1949. for (i = 0; i < (OldBloc.usLen <= 8 ? OldBloc.usLen : 8); i++)
  1950. {
  1951. fprintf(pfdLog, "%c", OldBloc.pData[i]);
  1952. }
  1953. fprintf(pfdLog, ")\n");
  1954. #endif
  1955. BestBloc = OldBloc;
  1956. BestAlgoId = ALGO_NONE;
  1957. #ifdef _ALGO_1
  1958. rv = CC_GenericCompress(&OldBloc, &CompBloc, ALGO_ACFX8);
  1959. if (rv == RV_MALLOC_FAILED) return rv;
  1960. // The compression algorithm may return RV_COMPRESSION_FAILED when
  1961. // the compression algorithm wants to use MORE space than the input data.
  1962. // In such a case, the algorithm returns the raw data in the compressed block
  1963. if (CompBloc.usLen < BestBloc.usLen)
  1964. {
  1965. /* On pr�serve OldBloc.pData qui sert pour les autres algos */
  1966. if (BestBloc.pData != OldBloc.pData)
  1967. {
  1968. GMEM_Free(BestBloc.pData);
  1969. }
  1970. BestBloc = CompBloc;
  1971. BestAlgoId = ALGO_ACFX8;
  1972. }
  1973. else
  1974. {
  1975. GMEM_Free(CompBloc.pData);
  1976. }
  1977. #endif
  1978. #ifdef _ALGO_2
  1979. rv = CC_GenericCompress(&OldBloc, &CompBloc, ALGO_ACAD8);
  1980. if (rv == RV_MALLOC_FAILED) return rv;
  1981. // The compression algorithm may return RV_COMPRESSION_FAILED when
  1982. // the compression algorithm wants to use MORE space than the input data.
  1983. // In such a case, the algorithm returns the raw data in the compressed block
  1984. if (CompBloc.usLen < BestBloc.usLen)
  1985. {
  1986. /* On pr�serve OldBloc.pData qui sert pour les autres algos */
  1987. if (BestBloc.pData != OldBloc.pData)
  1988. {
  1989. GMEM_Free(BestBloc.pData);
  1990. }
  1991. BestBloc = CompBloc;
  1992. BestAlgoId = ALGO_ACAD8;
  1993. }
  1994. else
  1995. {
  1996. GMEM_Free(CompBloc.pData);
  1997. }
  1998. #endif
  1999. if (BestBloc.usLen < 0x1F) /* La valeur 0x1F peut engendrer 0xFF = ESCAPE_CHAR */
  2000. {
  2001. if ((pData = GMEM_Alloc(BestBloc.usLen + 1)) == NULL_PTR)
  2002. {
  2003. GMEM_Free(BestBloc.pData);
  2004. return(RV_MALLOC_FAILED);
  2005. }
  2006. else
  2007. {
  2008. pData[0] = (BestAlgoId << 5) | BestBloc.usLen;
  2009. memcpy(&pData[1], BestBloc.pData, BestBloc.usLen);
  2010. pOutBloc->usLen = BestBloc.usLen + 1;
  2011. pOutBloc->pData = pData;
  2012. GMEM_Free(BestBloc.pData);
  2013. }
  2014. }
  2015. else if (BestBloc.usLen < 0x2000)
  2016. {
  2017. if ((pData = GMEM_Alloc(BestBloc.usLen + 3)) == NULL_PTR)
  2018. {
  2019. GMEM_Free(BestBloc.pData);
  2020. return(RV_MALLOC_FAILED);
  2021. }
  2022. else
  2023. {
  2024. pData[0] = ESCAPE_CHAR;
  2025. pData[1] = (BestAlgoId << 5) | (BestBloc.usLen >> 8);
  2026. pData[2] = BestBloc.usLen & 0xFF;
  2027. memcpy(&pData[3], BestBloc.pData, BestBloc.usLen);
  2028. pOutBloc->usLen = BestBloc.usLen + 3;
  2029. pOutBloc->pData = pData;
  2030. GMEM_Free(BestBloc.pData);
  2031. }
  2032. }
  2033. else
  2034. {
  2035. GMEM_Free(BestBloc.pData);
  2036. return(RV_INVALID_DATA);
  2037. }
  2038. return(RV_SUCCESS);
  2039. }
  2040. /*******************************************************************************
  2041. * int CC_RawDecode(BYTE *pInBloc,
  2042. * BLOC *pOutBloc,
  2043. * USHORT *pLength,
  2044. * BOOL bUseDictionnary
  2045. * )
  2046. *
  2047. * Description : Transformation inverse de 'CC_RawEncode'.
  2048. *
  2049. * Remarks :
  2050. *
  2051. * In : pInBloc : le bloc dcoder
  2052. * bUseDictionary : on peut ne pas utiliser le dictionnaire (doit
  2053. * tre consistent avec l'encodage)
  2054. *
  2055. * Out : pOutBloc : le bloc dcod (mmoire alloue ici librer par le
  2056. * programme appelant)
  2057. * pLength : la longueur de donnes encods utilise
  2058. *
  2059. * Responses : RV_SUCCESS : All is OK.
  2060. * RV_MALLOC_FAILED : Un malloc a chou.
  2061. * Autre : D'autres codes d'erreur peuvent tre retourns par des
  2062. * fonctions d'un niveau infrieur.
  2063. *
  2064. *******************************************************************************/
  2065. int CC_RawDecode(BYTE *pInData,
  2066. BLOC *pOutBloc,
  2067. USHORT *pLength,
  2068. BOOL bUseDictionary
  2069. )
  2070. {
  2071. BLOC
  2072. OldBloc,
  2073. NewBloc,
  2074. RecordBloc,
  2075. CompData;
  2076. BYTE
  2077. AlgoId;
  2078. int
  2079. rv;
  2080. USHORT
  2081. pos,
  2082. usIndex;
  2083. if (pInData[0] == ESCAPE_CHAR)
  2084. {
  2085. AlgoId = pInData[1] >> 5;
  2086. CompData.usLen = ((pInData[1] & 0x1F) << 8) + pInData[2];
  2087. CompData.pData = &(pInData[3]);
  2088. *pLength = CompData.usLen + 3;
  2089. }
  2090. else
  2091. {
  2092. AlgoId = pInData[0] >> 5;
  2093. CompData.usLen = pInData[0] & 0x1F;
  2094. CompData.pData = &(pInData[1]);
  2095. *pLength = CompData.usLen + 1;
  2096. }
  2097. rv = CC_GenericUncompress(&CompData, &OldBloc, AlgoId);
  2098. if (rv != RV_SUCCESS) return rv;
  2099. if (bUseDictionary)
  2100. {
  2101. pos = 0;
  2102. while (pos < OldBloc.usLen)
  2103. {
  2104. if (OldBloc.pData[pos] == ESCAPE_CHAR)
  2105. {
  2106. if (OldBloc.pData[pos + 1] == ESCAPE_CHAR)
  2107. {
  2108. NewBloc.usLen = OldBloc.usLen - 1;
  2109. if ((NewBloc.pData = GMEM_Alloc(NewBloc.usLen)) == NULL_PTR)
  2110. {
  2111. GMEM_Free(OldBloc.pData);
  2112. return(RV_MALLOC_FAILED);
  2113. }
  2114. memcpy(NewBloc.pData, OldBloc.pData, pos);
  2115. NewBloc.pData[pos] = ESCAPE_CHAR;
  2116. memcpy(NewBloc.pData + pos + 1,
  2117. OldBloc.pData + pos + 2,
  2118. OldBloc.usLen - pos - 2);
  2119. GMEM_Free(OldBloc.pData);
  2120. OldBloc = NewBloc;
  2121. pos++;
  2122. }
  2123. else if (OldBloc.pData[pos + 1] < 0x80)
  2124. {
  2125. usIndex = OldBloc.pData[pos + 1];
  2126. rv = SearchDataByIndex(usIndex, pDictMemory, &RecordBloc);
  2127. if (rv != RV_SUCCESS)
  2128. {
  2129. GMEM_Free(OldBloc.pData);
  2130. return rv;
  2131. }
  2132. NewBloc.usLen = OldBloc.usLen - 2 + RecordBloc.usLen;
  2133. if ((NewBloc.pData = GMEM_Alloc(NewBloc.usLen)) == NULL_PTR)
  2134. {
  2135. GMEM_Free(OldBloc.pData);
  2136. return(RV_MALLOC_FAILED);
  2137. }
  2138. memcpy(NewBloc.pData, OldBloc.pData, pos);
  2139. memcpy(NewBloc.pData + pos, RecordBloc.pData, RecordBloc.usLen);
  2140. memcpy(NewBloc.pData + pos + RecordBloc.usLen,
  2141. OldBloc.pData + pos + 2,
  2142. OldBloc.usLen - pos - 2);
  2143. GMEM_Free(OldBloc.pData);
  2144. OldBloc = NewBloc;
  2145. pos += RecordBloc.usLen;
  2146. }
  2147. else
  2148. {
  2149. usIndex = ((OldBloc.pData[pos + 1] & 0x7F) << 8) + OldBloc.pData[pos + 2];
  2150. rv = SearchDataByIndex(usIndex, pDictMemory, &RecordBloc);
  2151. if (rv != RV_SUCCESS)
  2152. {
  2153. GMEM_Free(OldBloc.pData);
  2154. return rv;
  2155. }
  2156. NewBloc.usLen = OldBloc.usLen - 3 + RecordBloc.usLen;
  2157. if ((NewBloc.pData = GMEM_Alloc(NewBloc.usLen)) == NULL_PTR)
  2158. {
  2159. GMEM_Free(OldBloc.pData);
  2160. return(RV_MALLOC_FAILED);
  2161. }
  2162. memcpy(NewBloc.pData, OldBloc.pData, pos);
  2163. memcpy(NewBloc.pData + pos, RecordBloc.pData, RecordBloc.usLen);
  2164. memcpy(NewBloc.pData + pos + RecordBloc.usLen,
  2165. OldBloc.pData + pos + 3,
  2166. OldBloc.usLen - pos - 3);
  2167. GMEM_Free(OldBloc.pData);
  2168. OldBloc = NewBloc;
  2169. pos += RecordBloc.usLen;
  2170. }
  2171. }
  2172. else
  2173. {
  2174. pos++;
  2175. }
  2176. }
  2177. }
  2178. *pOutBloc = OldBloc;
  2179. return(RV_SUCCESS);
  2180. }
  2181. /*******************************************************************************
  2182. * int CC_GenericCompress(BLOC *pUncompBloc,
  2183. * BLOC *pCompBloc,
  2184. * BYTE AlgoId
  2185. * )
  2186. *
  2187. * Description : Effectue une compression statistique sur la donne d'entre en
  2188. * utilisant l'algorithme spcifi dans AlgoId.
  2189. *
  2190. * Remarks : Si l'algorithme spcifi n'est pas implment, renvoie la donne
  2191. * originale.
  2192. *
  2193. * In : pUncompBloc : la donne compresser
  2194. * AlgoId : numro de l'algorithme employer
  2195. *
  2196. * Out : pCompBloc : la donne compresse (mmoire alloue ici librer
  2197. * par la fonction appelante)
  2198. *
  2199. * Responses : RV_SUCCESS : All is OK.
  2200. * RV_MALLOC_FAILED : Un malloc a chou.
  2201. *
  2202. *******************************************************************************/
  2203. int CC_GenericCompress(BLOC *pUncompBloc,
  2204. BLOC *pCompBloc,
  2205. BYTE AlgoId
  2206. )
  2207. {
  2208. switch(AlgoId)
  2209. {
  2210. #ifdef _ALGO_1
  2211. case ALGO_ACFX8 : /* Arithmetic coding, byte oriented, fixed model */
  2212. {
  2213. if (AcFx8_Encode(pUncompBloc, pCompBloc) != RV_SUCCESS)
  2214. {
  2215. return(RV_INVALID_DATA);
  2216. }
  2217. break;
  2218. }
  2219. #endif
  2220. #ifdef _ALGO_2
  2221. case ALGO_ACAD8 : /* Arithmetic coding, byte oriented, adaptative model */
  2222. {
  2223. if (AcAd8_Encode(pUncompBloc, pCompBloc) != RV_SUCCESS)
  2224. {
  2225. return(RV_INVALID_DATA);
  2226. }
  2227. break;
  2228. }
  2229. #endif
  2230. default :
  2231. {
  2232. if ((pCompBloc->pData = GMEM_Alloc(pUncompBloc->usLen)) == NULL_PTR)
  2233. {
  2234. return(RV_MALLOC_FAILED);
  2235. }
  2236. pCompBloc->usLen = pUncompBloc->usLen;
  2237. memcpy(pCompBloc->pData, pUncompBloc->pData, pCompBloc->usLen);
  2238. break;
  2239. }
  2240. }
  2241. #ifdef _STUDY
  2242. fprintf(pfdLog, "Algo : %d | 0x%04x (%04d) -> 0x%04x (%04d)", AlgoId,
  2243. pUncompBloc->usLen, pUncompBloc->usLen,
  2244. pCompBloc->usLen, pCompBloc->usLen
  2245. );
  2246. if (pUncompBloc->usLen > pCompBloc->usLen)
  2247. {
  2248. fprintf(pfdLog, " | %d", pCompBloc->usLen - pUncompBloc->usLen);
  2249. }
  2250. fprintf(pfdLog, "\n");
  2251. #endif
  2252. return(RV_SUCCESS);
  2253. }
  2254. /*******************************************************************************
  2255. * int CC_GenericUncompress(BLOC *pCompBloc,
  2256. * BLOC *pUncompBloc,
  2257. * BYTE AlgoID
  2258. * )
  2259. *
  2260. * Description : Effectue une dcompression statistique sur la donne d'entre en
  2261. * utilisant l'algorithme spcifi dans AlgoId.
  2262. *
  2263. * Remarks :
  2264. *
  2265. * In : pUncompBloc : la donne dcompresser
  2266. * AlgoId : numro de l'algorithme employer
  2267. *
  2268. * Out : pCompBloc : la donne dcompresse (mmoire alloue ici
  2269. * librer par la fonction appelante)
  2270. *
  2271. * Responses : RV_SUCCESS : All is OK.
  2272. * RV_MALLOC_FAILED : Un malloc a chou.
  2273. * RV_INVALID_DATA : L'algorithme spcifi n'existe pas.
  2274. *
  2275. *******************************************************************************/
  2276. int CC_GenericUncompress(BLOC *pCompBloc,
  2277. BLOC *pUncompBloc,
  2278. BYTE AlgoId
  2279. )
  2280. {
  2281. switch(AlgoId)
  2282. {
  2283. case ALGO_NONE :
  2284. pUncompBloc->usLen = pCompBloc->usLen;
  2285. if ((pUncompBloc->pData = GMEM_Alloc(pUncompBloc->usLen)) == NULL_PTR)
  2286. {
  2287. return(RV_MALLOC_FAILED);
  2288. }
  2289. memcpy(pUncompBloc->pData, pCompBloc->pData, pUncompBloc->usLen);
  2290. break;
  2291. #ifdef _ALGO_1
  2292. case ALGO_ACFX8 :
  2293. if (AcFx8_Decode(pCompBloc, pUncompBloc) != RV_SUCCESS)
  2294. {
  2295. return(RV_INVALID_DATA);
  2296. }
  2297. break;
  2298. #endif
  2299. #ifdef _ALGO_2
  2300. case ALGO_ACAD8 :
  2301. if (AcAd8_Decode(pCompBloc, pUncompBloc) != RV_SUCCESS)
  2302. {
  2303. return(RV_INVALID_DATA);
  2304. }
  2305. break;
  2306. #endif
  2307. default :
  2308. return(RV_INVALID_DATA);
  2309. break;
  2310. }
  2311. return(RV_SUCCESS);
  2312. }
  2313. /*******************************************************************************
  2314. * int CC_Encode_TBSCertificate(BLOC *pInBloc,
  2315. * BLOC *pOutBloc
  2316. * )
  2317. *
  2318. * Description : Encode une donne de type TBSCertificate.
  2319. * Ceci consiste en l'clatement en ses diffrents composants,
  2320. * leurs dsenrobages Asn1 et leurs encodages respectifs, et la
  2321. * concatnation de ces rsultats.
  2322. *
  2323. * Remarks : Certaines parties d'un TBSCertificate sont optionnelles. On
  2324. * dtecte pour chacune d'elles si elle est prsente et on
  2325. * l'indique dans des bits rservs d'un octet de contrle plac
  2326. * en dbut du rsultat encod. Cet octet de contrle contient
  2327. * galement le numro de version X.509 du certificat.
  2328. *
  2329. * In : pInBloc : la partie encoder (champ Content)
  2330. *
  2331. * Out : pOutBloc : l'encod (mmoire alloue ici librer par la
  2332. * fonction appelante)
  2333. *
  2334. * Responses : RV_SUCCESS : All is OK.
  2335. * RV_MALLOC_FAILED : Un malloc a chou.
  2336. * Autre : D'autres codes d'erreur peuvent tre retourns par des
  2337. * fonctions d'un niveau infrieur.
  2338. *
  2339. *******************************************************************************/
  2340. int CC_Encode_TBSCertificate(BLOC *pInBloc,
  2341. BLOC *pOutBloc
  2342. )
  2343. {
  2344. ASN1
  2345. serialNumberPart,
  2346. signaturePart,
  2347. issuerPart,
  2348. validityPart,
  2349. subjectPart,
  2350. subjectPKInfoPart,
  2351. issuerUIDPart,
  2352. subjectUIDPart,
  2353. extensionsPart;
  2354. BLOC
  2355. serialNumberEncoded,
  2356. signatureEncoded,
  2357. issuerEncoded,
  2358. validityEncoded,
  2359. subjectEncoded,
  2360. subjectPKInfoEncoded,
  2361. issuerUIDEncoded,
  2362. subjectUIDEncoded,
  2363. extensionsEncoded;
  2364. BOOL
  2365. bVersionPresent = FALSE,
  2366. bIssuerUIDPresent = FALSE,
  2367. bSubjectUIDPresent = FALSE,
  2368. bExtensionsPresent = FALSE;
  2369. BYTE
  2370. *pCurrent;
  2371. int
  2372. rv;
  2373. USHORT
  2374. usVersion = 0;
  2375. /* D�composition du tbsCertificate en ses diff�rents composants */
  2376. pCurrent = pInBloc->pData;
  2377. if (pCurrent[0] == TAG_OPTION_VERSION)
  2378. {
  2379. /* On a alors A0 03 02 01 vv o� vv est la version */
  2380. bVersionPresent = TRUE;
  2381. usVersion = pCurrent[4];
  2382. pCurrent += 5;
  2383. }
  2384. serialNumberPart.Asn1.pData = pCurrent;
  2385. rv = CC_ExtractContent(&serialNumberPart);
  2386. if (rv != RV_SUCCESS) return rv;
  2387. pCurrent = serialNumberPart.Content.pData + serialNumberPart.Content.usLen;
  2388. signaturePart.Asn1.pData = pCurrent;
  2389. rv = CC_ExtractContent(&signaturePart);
  2390. if (rv != RV_SUCCESS) return rv;
  2391. pCurrent = signaturePart.Content.pData + signaturePart.Content.usLen;
  2392. issuerPart.Asn1.pData = pCurrent;
  2393. rv = CC_ExtractContent(&issuerPart);
  2394. if (rv != RV_SUCCESS) return rv;
  2395. pCurrent = issuerPart.Content.pData + issuerPart.Content.usLen;
  2396. validityPart.Asn1.pData = pCurrent;
  2397. rv = CC_ExtractContent(&validityPart);
  2398. if (rv != RV_SUCCESS) return rv;
  2399. pCurrent = validityPart.Content.pData + validityPart.Content.usLen;
  2400. subjectPart.Asn1.pData = pCurrent;
  2401. rv = CC_ExtractContent(&subjectPart);
  2402. #ifdef _STUDY
  2403. // fprintf(pfdLog, "Subject : %d octets\n", subjectPart.Asn1.usLen);
  2404. #endif
  2405. if (rv != RV_SUCCESS) return rv;
  2406. pCurrent = subjectPart.Content.pData + subjectPart.Content.usLen;
  2407. subjectPKInfoPart.Asn1.pData = pCurrent;
  2408. rv = CC_ExtractContent(&subjectPKInfoPart);
  2409. if (rv != RV_SUCCESS) return rv;
  2410. pCurrent = subjectPKInfoPart.Content.pData + subjectPKInfoPart.Content.usLen;
  2411. if (pCurrent[0] == TAG_OPTION_ISSUER_UID)
  2412. {
  2413. bIssuerUIDPresent = TRUE;
  2414. issuerUIDPart.Asn1.pData = pCurrent;
  2415. rv = CC_ExtractContent(&issuerUIDPart);
  2416. if (rv != RV_SUCCESS) return rv;
  2417. pCurrent = issuerUIDPart.Content.pData + issuerUIDPart.Content.usLen;
  2418. }
  2419. if (pCurrent[0] == TAG_OPTION_SUBJECT_UID)
  2420. {
  2421. bSubjectUIDPresent = TRUE;
  2422. subjectUIDPart.Asn1.pData = pCurrent;
  2423. rv = CC_ExtractContent(&subjectUIDPart);
  2424. if (rv != RV_SUCCESS) return rv;
  2425. pCurrent = subjectUIDPart.Content.pData + subjectUIDPart.Content.usLen;
  2426. }
  2427. if (pCurrent[0] == TAG_OPTION_EXTENSIONS)
  2428. {
  2429. bExtensionsPresent = TRUE;
  2430. extensionsPart.Asn1.pData = pCurrent;
  2431. rv = CC_ExtractContent(&extensionsPart);
  2432. if (rv != RV_SUCCESS) return rv;
  2433. pCurrent = extensionsPart.Content.pData + extensionsPart.Content.usLen;
  2434. }
  2435. /* Encodages des diff�rents composants et calcul de la longueur n�cessaire */
  2436. /* Les pData des blocs *Encoded sont allou�s par les fonctions CC_Encode_*.
  2437. Ils sont librs dans cette fonction aprs usage */
  2438. serialNumberEncoded.pData = NULL;
  2439. signatureEncoded.pData = NULL;
  2440. issuerEncoded.pData = NULL;
  2441. validityEncoded.pData = NULL;
  2442. subjectEncoded.pData = NULL;
  2443. subjectPKInfoEncoded.pData= NULL;
  2444. issuerUIDEncoded.pData = NULL;
  2445. subjectUIDEncoded.pData = NULL;
  2446. extensionsEncoded.pData = NULL;
  2447. pOutBloc->usLen = 1;
  2448. rv = CC_Encode_CertificateSerialNumber(&serialNumberPart.Content, &serialNumberEncoded);
  2449. if (rv != RV_SUCCESS) goto err;
  2450. pOutBloc->usLen += serialNumberEncoded.usLen;
  2451. rv = CC_Encode_AlgorithmIdentifier(&signaturePart.Content, &signatureEncoded);
  2452. if (rv != RV_SUCCESS) goto err;
  2453. pOutBloc->usLen += signatureEncoded.usLen;
  2454. rv = CC_Encode_Name(&issuerPart.Content, &issuerEncoded);
  2455. if (rv != RV_SUCCESS) goto err;
  2456. pOutBloc->usLen += issuerEncoded.usLen;
  2457. rv = CC_Encode_Validity(&validityPart.Content, &validityEncoded);
  2458. if (rv != RV_SUCCESS) goto err;
  2459. pOutBloc->usLen += validityEncoded.usLen;
  2460. rv = CC_Encode_Name(&subjectPart.Content, &subjectEncoded);
  2461. if (rv != RV_SUCCESS) goto err;
  2462. pOutBloc->usLen += subjectEncoded.usLen;
  2463. rv = CC_Encode_SubjectPKInfo(&subjectPKInfoPart.Content, &subjectPKInfoEncoded);
  2464. if (rv != RV_SUCCESS) goto err;
  2465. pOutBloc->usLen += subjectPKInfoEncoded.usLen;
  2466. if (bIssuerUIDPresent == TRUE)
  2467. {
  2468. rv = CC_Encode_UniqueIdentifier(&issuerUIDPart.Content, &issuerUIDEncoded);
  2469. if (rv != RV_SUCCESS) goto err;
  2470. pOutBloc->usLen += issuerUIDEncoded.usLen;
  2471. }
  2472. if (bSubjectUIDPresent == TRUE)
  2473. {
  2474. rv = CC_Encode_UniqueIdentifier(&subjectUIDPart.Content, &subjectUIDEncoded);
  2475. if (rv != RV_SUCCESS) goto err;
  2476. pOutBloc->usLen += subjectUIDEncoded.usLen;
  2477. }
  2478. if (bExtensionsPresent == TRUE)
  2479. {
  2480. rv = CC_Encode_Extensions(&extensionsPart.Content, &extensionsEncoded);
  2481. if (rv != RV_SUCCESS) goto err;
  2482. pOutBloc->usLen += extensionsEncoded.usLen;
  2483. }
  2484. /* Reconstruction � partir des composants */
  2485. /* A d�sallouer par le programme appelant */
  2486. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  2487. {
  2488. rv = RV_MALLOC_FAILED;
  2489. goto err;
  2490. }
  2491. pCurrent = pOutBloc->pData;
  2492. *pCurrent = 0x80 * (bVersionPresent == TRUE)
  2493. + 0x40 * (bIssuerUIDPresent == TRUE)
  2494. + 0x20 * (bSubjectUIDPresent == TRUE)
  2495. + 0x10 * (bExtensionsPresent == TRUE)
  2496. + usVersion;
  2497. pCurrent++;
  2498. memcpy(pCurrent, serialNumberEncoded.pData, serialNumberEncoded.usLen);
  2499. GMEM_Free(serialNumberEncoded.pData);
  2500. pCurrent += serialNumberEncoded.usLen;
  2501. memcpy(pCurrent, signatureEncoded.pData, signatureEncoded.usLen);
  2502. GMEM_Free(signatureEncoded.pData);
  2503. pCurrent += signatureEncoded.usLen;
  2504. memcpy(pCurrent, issuerEncoded.pData, issuerEncoded.usLen);
  2505. GMEM_Free(issuerEncoded.pData);
  2506. pCurrent += issuerEncoded.usLen;
  2507. memcpy(pCurrent, validityEncoded.pData, validityEncoded.usLen);
  2508. GMEM_Free(validityEncoded.pData);
  2509. pCurrent += validityEncoded.usLen;
  2510. memcpy(pCurrent, subjectEncoded.pData, subjectEncoded.usLen);
  2511. GMEM_Free(subjectEncoded.pData);
  2512. pCurrent += subjectEncoded.usLen;
  2513. memcpy(pCurrent, subjectPKInfoEncoded.pData, subjectPKInfoEncoded.usLen);
  2514. GMEM_Free(subjectPKInfoEncoded.pData);
  2515. pCurrent += subjectPKInfoEncoded.usLen;
  2516. if (bIssuerUIDPresent == TRUE)
  2517. {
  2518. memcpy(pCurrent, issuerUIDEncoded.pData, issuerUIDEncoded.usLen);
  2519. GMEM_Free(issuerUIDEncoded.pData);
  2520. pCurrent += issuerUIDEncoded.usLen;
  2521. }
  2522. if (bSubjectUIDPresent == TRUE)
  2523. {
  2524. memcpy(pCurrent, subjectUIDEncoded.pData, subjectUIDEncoded.usLen);
  2525. GMEM_Free(subjectUIDEncoded.pData);
  2526. pCurrent += subjectUIDEncoded.usLen;
  2527. }
  2528. if (bExtensionsPresent == TRUE)
  2529. {
  2530. memcpy(pCurrent, extensionsEncoded.pData, extensionsEncoded.usLen);
  2531. GMEM_Free(extensionsEncoded.pData);
  2532. pCurrent += extensionsEncoded.usLen;
  2533. }
  2534. return(RV_SUCCESS);
  2535. err:
  2536. GMEM_Free(serialNumberEncoded.pData);
  2537. GMEM_Free(signatureEncoded.pData);
  2538. GMEM_Free(issuerEncoded.pData);
  2539. GMEM_Free(validityEncoded.pData);
  2540. GMEM_Free(subjectEncoded.pData);
  2541. GMEM_Free(subjectPKInfoEncoded.pData);
  2542. GMEM_Free(issuerUIDEncoded.pData);
  2543. GMEM_Free(subjectUIDEncoded.pData);
  2544. GMEM_Free(extensionsEncoded.pData);
  2545. return rv;
  2546. }
  2547. /*******************************************************************************
  2548. * int CC_Encode_CertificateSerialNumber(BLOC *pInBloc,
  2549. * BLOC *pOutBloc
  2550. * )
  2551. *
  2552. * Description : Encode une donne de type CertificateSerialNumber.
  2553. * Ceci consiste seulement en l'encodage brute (CC_RawEncode) de la
  2554. * donne d'entre.
  2555. *
  2556. * Remarks :
  2557. *
  2558. * In : pInBloc : la partie encoder (champ Content)
  2559. *
  2560. * Out : pOutBloc : l'encod (mmoire alloue ici librer par la
  2561. * fonction appelante)
  2562. *
  2563. * Responses : RV_SUCCESS : All is OK.
  2564. * Autre : D'autres codes d'erreur peuvent tre retourns par des
  2565. * fonctions d'un niveau infrieur.
  2566. *
  2567. *******************************************************************************/
  2568. int CC_Encode_CertificateSerialNumber(BLOC *pInBloc,
  2569. BLOC *pOutBloc
  2570. )
  2571. {
  2572. int
  2573. rv;
  2574. rv = CC_RawEncode(pInBloc, pOutBloc, TRUE);
  2575. if (rv != RV_SUCCESS) return rv;
  2576. return(RV_SUCCESS);
  2577. }
  2578. /*******************************************************************************
  2579. * int CC_Encode_AlgorithmIdentifier(BLOC *pInBloc,
  2580. * BLOC *pOutBloc
  2581. * )
  2582. *
  2583. * Description : Encode une donne de type AlgorithmIdentifier.
  2584. * Ceci consiste en l'clatement en ses diffrents composants,
  2585. * leurs dsenrobages Asn1 et leurs encodages respectifs, et la
  2586. * concatnation de ces rsultats.
  2587. *
  2588. * Remarks : bNullParam sert coder sur un bit l'information qu'il n'y a pas
  2589. * de paramtre l'algorithme. Cette information occupe toujours
  2590. * deux octets dans le certificat est vaut toujours {0x05, 0x00}.
  2591. * On utilise un dictionnaire statique (dfini au dbut de ce
  2592. * source) pour remplacer le type d'algorithme par un index.
  2593. * Un octet de contrle (en dbut du rsultat) indique, ou bien que
  2594. * l'on n'a pas trouv le type d'algo dans le dico (valeur 0xFF ->
  2595. * Encodage brut de la donne d'entre intgrale), ou bien un flag
  2596. * prcisant s'il y a des paramtres et l'index du type d'algo.
  2597. *
  2598. * In : pInBloc : la partie encoder (champ Content)
  2599. *
  2600. * Out : pOutBloc : l'encod (mmoire alloue ici librer par la
  2601. * fonction appelante)
  2602. *
  2603. * Responses : RV_SUCCESS : All is OK.
  2604. * RV_MALLOC_FAILED : Un malloc a chou.
  2605. * Autre : D'autres codes d'erreur peuvent tre retourns par des
  2606. * fonctions d'un niveau infrieur.
  2607. *
  2608. *******************************************************************************/
  2609. int CC_Encode_AlgorithmIdentifier(BLOC *pInBloc,
  2610. BLOC *pOutBloc
  2611. )
  2612. {
  2613. ASN1
  2614. AlgorithmPart,
  2615. ParametersPart;
  2616. BLOC
  2617. AlgorithmIdentifierEncoded,
  2618. ParametersAsn1Encoded;
  2619. BOOL
  2620. bFound,
  2621. bNoParam = FALSE,
  2622. bNullParam = FALSE;
  2623. int
  2624. rv;
  2625. USHORT
  2626. Index,
  2627. AlgoIndex;
  2628. AlgorithmPart.Asn1.pData = pInBloc->pData;
  2629. rv = CC_ExtractContent(&AlgorithmPart);
  2630. if (rv != RV_SUCCESS) return rv;
  2631. if (AlgorithmPart.Asn1.usLen == pInBloc->usLen)
  2632. {
  2633. bNoParam = TRUE;
  2634. bNullParam = FALSE;
  2635. }
  2636. else
  2637. {
  2638. ParametersPart.Asn1.pData = AlgorithmPart.Content.pData + AlgorithmPart.Content.usLen;
  2639. rv = CC_ExtractContent(&ParametersPart);
  2640. if (rv != RV_SUCCESS) return rv;
  2641. if (ParametersPart.Content.usLen == 0)
  2642. {
  2643. bNoParam = TRUE;
  2644. bNullParam = TRUE;
  2645. }
  2646. }
  2647. /* Recherche de l'identifiant de l'algorithme dans le dictionnaire */
  2648. Index = 0;
  2649. bFound = FALSE;
  2650. while ((bFound == FALSE) && (AlgorithmTypeDict[Index] != NULL))
  2651. {
  2652. if (!memcmp(AlgorithmTypeDict[Index],
  2653. AlgorithmPart.Content.pData,
  2654. AlgorithmPart.Content.usLen))
  2655. {
  2656. bFound = TRUE;
  2657. AlgoIndex = Index;
  2658. }
  2659. Index++;
  2660. }
  2661. /* Construction de l'encodage */
  2662. if (bFound == TRUE)
  2663. {
  2664. if (bNoParam == TRUE)
  2665. {
  2666. if (bNullParam == TRUE)
  2667. {
  2668. /* Si on a trouv� l'algorithme et il n'y a pas de param�tre */
  2669. pOutBloc->usLen = 1;
  2670. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  2671. {
  2672. return (RV_MALLOC_FAILED);
  2673. }
  2674. pOutBloc->pData[0] = (AlgoIndex | 0x80);
  2675. }
  2676. else
  2677. {
  2678. pOutBloc->usLen = 2;
  2679. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  2680. {
  2681. return (RV_MALLOC_FAILED);
  2682. }
  2683. pOutBloc->pData[0] = ABSENT_PARAMETER_CHAR;
  2684. pOutBloc->pData[1] = (BYTE) AlgoIndex;
  2685. }
  2686. }
  2687. else
  2688. {
  2689. /* Si on a trouv� l'algorithme et il y a des param�tres */
  2690. /* On RawEncode non pas le contenu des param�tres mais l'Asn1 entier
  2691. car on n'est pas sr de l'encapsulage */
  2692. rv = CC_RawEncode(&(ParametersPart.Asn1), &ParametersAsn1Encoded, TRUE);
  2693. if (rv != RV_SUCCESS) return rv;
  2694. pOutBloc->usLen = 1 + ParametersAsn1Encoded.usLen;
  2695. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  2696. {
  2697. GMEM_Free(ParametersAsn1Encoded.pData);
  2698. return (RV_MALLOC_FAILED);
  2699. }
  2700. pOutBloc->pData[0] = (BYTE) AlgoIndex;
  2701. memcpy(&(pOutBloc->pData[1]),
  2702. ParametersAsn1Encoded.pData,
  2703. ParametersAsn1Encoded.usLen);
  2704. GMEM_Free(ParametersAsn1Encoded.pData);
  2705. }
  2706. }
  2707. else
  2708. {
  2709. /* Si on n'a pas trouv� l'algorithme dans le dictionnaire */
  2710. /* On RawEncode le contenu de AlgorithmIdentifier c'est � dire la
  2711. concatnation du asn1 de AlgorithmPart et du asn1 de ParametersPart */
  2712. rv = CC_RawEncode(pInBloc, &AlgorithmIdentifierEncoded, TRUE);
  2713. if (rv != RV_SUCCESS) return rv;
  2714. pOutBloc->usLen = 1 + AlgorithmIdentifierEncoded.usLen;
  2715. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  2716. {
  2717. GMEM_Free(AlgorithmIdentifierEncoded.pData);
  2718. return (RV_MALLOC_FAILED);
  2719. }
  2720. pOutBloc->pData[0] = ESCAPE_CHAR;
  2721. memcpy(&(pOutBloc->pData[1]),
  2722. AlgorithmIdentifierEncoded.pData,
  2723. AlgorithmIdentifierEncoded.usLen);
  2724. GMEM_Free(AlgorithmIdentifierEncoded.pData);
  2725. }
  2726. return (RV_SUCCESS);
  2727. }
  2728. /*******************************************************************************
  2729. * int CC_Encode_Name(BLOC *pInBloc,
  2730. * BLOC *pOutBloc
  2731. * )
  2732. *
  2733. * Description : Encode une donne de type Name.
  2734. * Ceci consiste en l'clatement en ses diffrents composants,
  2735. * leurs dsenrobages Asn1 et leurs encodages respectifs, et la
  2736. * concatnation de ces rsultats.
  2737. *
  2738. * Remarks : Un octet de contrle (en dbut du rsultat) indique le nombre
  2739. * de RelativeDistinguishedName dont est compos le Name.
  2740. *
  2741. * In : pInBloc : la partie encoder (champ Content)
  2742. *
  2743. * Out : pOutBloc : l'encod (mmoire alloue ici librer par la
  2744. * fonction appelante)
  2745. *
  2746. * Responses : RV_SUCCESS : All is OK.
  2747. * RV_MALLOC_FAILED : Un malloc a chou.
  2748. * Autre : D'autres codes d'erreur peuvent tre retourns par des
  2749. * fonctions d'un niveau infrieur.
  2750. *
  2751. *******************************************************************************/
  2752. int CC_Encode_Name(BLOC *pInBloc,
  2753. BLOC *pOutBloc
  2754. )
  2755. {
  2756. ASN1
  2757. RDN[MAX_RDN];
  2758. BLOC
  2759. RDNEncoded[MAX_RDN];
  2760. BYTE
  2761. *pCurrent;
  2762. USHORT
  2763. i,
  2764. usNbRDN;
  2765. int
  2766. rv;
  2767. /* D�composition du Name en ses diff�rents RelativeDistinguishedName */
  2768. pCurrent = pInBloc->pData;
  2769. usNbRDN = 0;
  2770. while (pCurrent < pInBloc->pData + pInBloc->usLen)
  2771. {
  2772. RDN[usNbRDN].Asn1.pData = pCurrent;
  2773. rv = CC_ExtractContent(&(RDN[usNbRDN]));
  2774. if (rv != RV_SUCCESS) return rv;
  2775. pCurrent = RDN[usNbRDN].Content.pData + RDN[usNbRDN].Content.usLen;
  2776. usNbRDN++;
  2777. }
  2778. ASSERT(pCurrent == pInBloc->pData + pInBloc->usLen);
  2779. /* Encodages des diff�rents composants et calcul de la longueur n�cessaire */
  2780. for (i = 0; i < usNbRDN; i++)
  2781. {
  2782. RDNEncoded[i].pData = NULL;
  2783. }
  2784. pOutBloc->usLen = 1;
  2785. for (i = 0; i < usNbRDN; i++)
  2786. {
  2787. rv = CC_Encode_RDN(&RDN[i].Content, &RDNEncoded[i]);
  2788. if (rv != RV_SUCCESS) goto err;
  2789. pOutBloc->usLen += RDNEncoded[i].usLen;
  2790. }
  2791. /* Reconstruction � partir des composants */
  2792. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  2793. {
  2794. rv = RV_MALLOC_FAILED;
  2795. goto err;
  2796. }
  2797. pCurrent = pOutBloc->pData;
  2798. *pCurrent = (BYTE) usNbRDN;
  2799. pCurrent++;
  2800. for (i = 0; i < usNbRDN; i++)
  2801. {
  2802. memcpy(pCurrent, RDNEncoded[i].pData, RDNEncoded[i].usLen);
  2803. GMEM_Free(RDNEncoded[i].pData);
  2804. pCurrent += RDNEncoded[i].usLen;
  2805. }
  2806. return(RV_SUCCESS);
  2807. err:
  2808. for (i = 0; i < usNbRDN; i++)
  2809. {
  2810. GMEM_Free(RDNEncoded[i].pData);
  2811. }
  2812. return (rv);
  2813. }
  2814. /*******************************************************************************
  2815. * int CC_Encode_RDN(BLOC *pInBloc,
  2816. * BLOC *pOutBloc
  2817. * )
  2818. *
  2819. * Description : Encode une donne de type RelativeDistinguishedName (RDN).
  2820. * Ceci consiste en l'clatement en ses diffrents composants,
  2821. * leurs dsenrobages Asn1 et leurs encodages respectifs, et la
  2822. * concatnation de ces rsultats.
  2823. *
  2824. * Remarks : Un octet de contrle (en dbut du rsultat) indique le nombre
  2825. * de AttributeValueAssertion dont est compos le RDN.
  2826. *
  2827. * In : pInBloc : la partie encoder (champ Content)
  2828. *
  2829. * Out : pOutBloc : l'encod (mmoire alloue ici librer par la
  2830. * fonction appelante)
  2831. *
  2832. * Responses : RV_SUCCESS : All is OK.
  2833. * RV_MALLOC_FAILED : Un malloc a chou.
  2834. * Autre : D'autres codes d'erreur peuvent tre retourns par des
  2835. * fonctions d'un niveau infrieur.
  2836. *
  2837. *******************************************************************************/
  2838. int CC_Encode_RDN(BLOC *pInBloc,
  2839. BLOC *pOutBloc
  2840. )
  2841. {
  2842. ASN1
  2843. AVA[MAX_AVA];
  2844. BLOC
  2845. AVAEncoded[MAX_AVA];
  2846. BYTE
  2847. *pCurrent;
  2848. USHORT
  2849. i,
  2850. usNbAVA;
  2851. int
  2852. rv;
  2853. /* D�composition du RDN en ses diff�rents AVA */
  2854. pCurrent = pInBloc->pData;
  2855. usNbAVA = 0;
  2856. while (pCurrent < pInBloc->pData + pInBloc->usLen)
  2857. {
  2858. AVA[usNbAVA].Asn1.pData = pCurrent;
  2859. rv = CC_ExtractContent(&(AVA[usNbAVA]));
  2860. if (rv != RV_SUCCESS) return rv;
  2861. pCurrent = AVA[usNbAVA].Content.pData + AVA[usNbAVA].Content.usLen;
  2862. usNbAVA++;
  2863. }
  2864. ASSERT(pCurrent == pInBloc->pData + pInBloc->usLen);
  2865. /* Encodages des diff�rents composants et calcul de la longueur n�cessaire */
  2866. for (i = 0; i < usNbAVA; i++)
  2867. {
  2868. AVAEncoded[i].pData = NULL;
  2869. }
  2870. pOutBloc->usLen = 1;
  2871. for (i = 0; i < usNbAVA; i++)
  2872. {
  2873. rv = CC_Encode_AVA(&AVA[i].Content, &AVAEncoded[i]);
  2874. if (rv != RV_SUCCESS) goto err;
  2875. pOutBloc->usLen += AVAEncoded[i].usLen;
  2876. }
  2877. /* Reconstruction � partir des composants */
  2878. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  2879. {
  2880. rv = RV_MALLOC_FAILED;
  2881. goto err;
  2882. }
  2883. pCurrent = pOutBloc->pData;
  2884. *pCurrent = (BYTE) usNbAVA;
  2885. pCurrent++;
  2886. for (i = 0; i < usNbAVA; i++)
  2887. {
  2888. memcpy(pCurrent, AVAEncoded[i].pData, AVAEncoded[i].usLen);
  2889. GMEM_Free(AVAEncoded[i].pData);
  2890. pCurrent += AVAEncoded[i].usLen;
  2891. }
  2892. return(RV_SUCCESS);
  2893. err:
  2894. for (i = 0; i < usNbAVA; i++)
  2895. {
  2896. GMEM_Free(AVAEncoded[i].pData);
  2897. }
  2898. return(rv);
  2899. }
  2900. /*******************************************************************************
  2901. * int CC_Encode_AVA(BLOC *pInBloc,
  2902. * BLOC *pOutBloc
  2903. * )
  2904. *
  2905. * Description : Encode une donne de type AttributeValueAssertion (AVA).
  2906. * Ceci consiste en l'clatement en ses diffrents composants,
  2907. * leurs dsenrobages Asn1 et leurs encodages respectifs, et la
  2908. * concatnation de ces rsultats.
  2909. *
  2910. * Remarks : On utilise un dictionnaire statique (dfini au dbut de ce
  2911. * source) pour remplacer le type d'attribut par un index.
  2912. * Un octet de contrle (en dbut du rsultat) indique, ou bien que
  2913. * l'on n'a pas trouv le type d'attribut dans le dico (0xFF)
  2914. * ou l'index du type d'attribut.
  2915. * On ne code pas le Content de AttributeValue mais son Asn1 car on
  2916. * n'est pas sr du tag employ.
  2917. *
  2918. * In : pInBloc : la partie encoder (champ Content)
  2919. *
  2920. * Out : pOutBloc : l'encod (mmoire alloue ici librer par la
  2921. * fonction appelante)
  2922. *
  2923. * Responses : RV_SUCCESS : All is OK.
  2924. * RV_MALLOC_FAILED : Un malloc a chou.
  2925. * Autre : D'autres codes d'erreur peuvent tre retourns par des
  2926. * fonctions d'un niveau infrieur.
  2927. *
  2928. *******************************************************************************/
  2929. int CC_Encode_AVA(BLOC *pInBloc,
  2930. BLOC *pOutBloc
  2931. )
  2932. {
  2933. ASN1
  2934. AttributeTypePart,
  2935. AttributeValuePart;
  2936. BLOC
  2937. AttributeTypeEncoded,
  2938. AttributeValueEncoded;
  2939. BOOL
  2940. bFound;
  2941. USHORT
  2942. Index,
  2943. AttributeTypeIndex;
  2944. int
  2945. rv;
  2946. /* D�composition */
  2947. AttributeTypePart.Asn1.pData = pInBloc->pData;
  2948. rv = CC_ExtractContent(&AttributeTypePart);
  2949. if (rv != RV_SUCCESS) return rv;
  2950. AttributeValuePart.Asn1.pData = AttributeTypePart.Content.pData
  2951. + AttributeTypePart.Content.usLen;
  2952. rv = CC_ExtractContent(&AttributeValuePart); /* Pas n�cessaire */
  2953. if (rv != RV_SUCCESS) return rv;
  2954. /* Recherche de l'identifiant de l'AttributeType dans le dictionnaire */
  2955. Index = 0;
  2956. bFound = FALSE;
  2957. while((bFound == FALSE) && (AttributeTypeDict[Index] != NULL))
  2958. {
  2959. if (!memcmp(AttributeTypeDict[Index],
  2960. AttributeTypePart.Content.pData,
  2961. AttributeTypePart.Content.usLen))
  2962. {
  2963. bFound = TRUE;
  2964. AttributeTypeIndex = Index;
  2965. }
  2966. Index++;
  2967. }
  2968. /* Construction de l'encodage */
  2969. /* Attention : on encode aussi l'enrobage de AttributeValue ! */
  2970. if (bFound == TRUE)
  2971. {
  2972. /* Il nous faut la longueur enrobage compris mais cette ligne est-elle
  2973. vraiment ncessaire ? */
  2974. AttributeValuePart.Asn1.usLen = (unsigned short) (DWORD)((pInBloc->pData + pInBloc->usLen)
  2975. - AttributeValuePart.Asn1.pData);
  2976. rv = CC_RawEncode(&(AttributeValuePart.Asn1), &AttributeValueEncoded, TRUE);
  2977. if (rv != RV_SUCCESS) return rv;
  2978. pOutBloc->usLen = 1 + AttributeValueEncoded.usLen;
  2979. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  2980. {
  2981. GMEM_Free(AttributeValueEncoded.pData);
  2982. return(RV_MALLOC_FAILED);
  2983. }
  2984. pOutBloc->pData[0] = (BYTE) AttributeTypeIndex;
  2985. memcpy(&(pOutBloc->pData[1]), AttributeValueEncoded.pData, AttributeValueEncoded.usLen);
  2986. GMEM_Free(AttributeValueEncoded.pData);
  2987. }
  2988. else
  2989. {
  2990. /* Si on n'a pas trouv� l'attribut dans le dictionnaire */
  2991. rv = CC_RawEncode(&(AttributeTypePart.Content), &AttributeTypeEncoded, TRUE);
  2992. if (rv != RV_SUCCESS) return rv;
  2993. rv = CC_RawEncode(&(AttributeValuePart.Asn1), &AttributeValueEncoded, TRUE);
  2994. if (rv != RV_SUCCESS)
  2995. {
  2996. GMEM_Free(AttributeTypeEncoded.pData);
  2997. return rv;
  2998. }
  2999. pOutBloc->usLen = 1
  3000. + AttributeTypeEncoded.usLen
  3001. + AttributeValueEncoded.usLen;
  3002. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  3003. {
  3004. GMEM_Free(AttributeTypeEncoded.pData);
  3005. GMEM_Free(AttributeValueEncoded.pData);
  3006. return(RV_MALLOC_FAILED);
  3007. }
  3008. pOutBloc->pData[0] = ESCAPE_CHAR;
  3009. memcpy(&(pOutBloc->pData[1]),
  3010. AttributeTypeEncoded.pData,
  3011. AttributeTypeEncoded.usLen);
  3012. memcpy(&(pOutBloc->pData[1 + AttributeTypeEncoded.usLen]),
  3013. AttributeValueEncoded.pData,
  3014. AttributeValueEncoded.usLen);
  3015. GMEM_Free(AttributeTypeEncoded.pData);
  3016. GMEM_Free(AttributeValueEncoded.pData);
  3017. }
  3018. return(RV_SUCCESS);
  3019. }
  3020. /*******************************************************************************
  3021. * int CC_Encode_Validity(BLOC *pInBloc,
  3022. * BLOC *pOutBloc
  3023. * )
  3024. *
  3025. * Description : Encode une donne de type Validity.
  3026. * Ceci consiste en l'clatement en ses diffrents composants,
  3027. * leurs dsenrobages Asn1 et leurs encodages respectifs, et la
  3028. * concatnation de ces rsultats.
  3029. *
  3030. * Remarks : Un octet de contrle (en dbut du rsultat) indique les formats
  3031. * des deux parties notBefore et notAfter.
  3032. *
  3033. * In : pInBloc : la partie encoder (champ Content)
  3034. *
  3035. * Out : pOutBloc : l'encod (mmoire alloue ici librer par la
  3036. * fonction appelante)
  3037. *
  3038. * Responses : RV_SUCCESS : All is OK.
  3039. * RV_MALLOC_FAILED : Un malloc a chou.
  3040. * Autre : D'autres codes d'erreur peuvent tre retourns par des
  3041. * fonctions d'un niveau infrieur.
  3042. *
  3043. *******************************************************************************/
  3044. int CC_Encode_Validity(BLOC *pInBloc,
  3045. BLOC *pOutBloc
  3046. )
  3047. {
  3048. ASN1
  3049. notBeforePart,
  3050. notAfterPart;
  3051. BLOC
  3052. notBeforeEncoded,
  3053. notAfterEncoded;
  3054. BYTE
  3055. notBeforeFormat,
  3056. notAfterFormat,
  3057. *pCurrent;
  3058. int
  3059. rv;
  3060. /* D�composition */
  3061. pCurrent = pInBloc->pData;
  3062. notBeforePart.Asn1.pData = pCurrent;
  3063. rv = CC_ExtractContent(&notBeforePart);
  3064. if (rv != RV_SUCCESS) return rv;
  3065. pCurrent = notBeforePart.Content.pData + notBeforePart.Content.usLen;
  3066. notAfterPart.Asn1.pData = pCurrent;
  3067. rv = CC_ExtractContent(&notAfterPart);
  3068. if (rv != RV_SUCCESS) return rv;
  3069. pCurrent = notAfterPart.Content.pData + notAfterPart.Content.usLen;
  3070. /* Encodages des diff�rents composants et calcul de la longueur n�cessaire */
  3071. pOutBloc->usLen = 1;
  3072. rv = CC_Encode_UTCTime(&notBeforePart.Content, &notBeforeEncoded, &notBeforeFormat);
  3073. if (rv != RV_SUCCESS) return rv;
  3074. pOutBloc->usLen += notBeforeEncoded.usLen;
  3075. rv = CC_Encode_UTCTime(&notAfterPart.Content, &notAfterEncoded, &notAfterFormat);
  3076. if (rv != RV_SUCCESS)
  3077. {
  3078. GMEM_Free(notBeforeEncoded.pData);
  3079. return rv;
  3080. }
  3081. pOutBloc->usLen += notAfterEncoded.usLen;
  3082. /* Reconstruction � partir des composants */
  3083. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  3084. {
  3085. GMEM_Free(notBeforeEncoded.pData);
  3086. GMEM_Free(notAfterEncoded.pData);
  3087. return(RV_MALLOC_FAILED);
  3088. }
  3089. pCurrent = pOutBloc->pData;
  3090. *pCurrent = (notBeforeFormat << 4) + notAfterFormat;
  3091. pCurrent++;
  3092. memcpy(pCurrent, notBeforeEncoded.pData, notBeforeEncoded.usLen);
  3093. GMEM_Free(notBeforeEncoded.pData);
  3094. pCurrent += notBeforeEncoded.usLen;
  3095. memcpy(pCurrent, notAfterEncoded.pData, notAfterEncoded.usLen);
  3096. GMEM_Free(notAfterEncoded.pData);
  3097. pCurrent += notAfterEncoded.usLen;
  3098. return(RV_SUCCESS);
  3099. }
  3100. /*******************************************************************************
  3101. * int CC_Encode_UTCTime(BLOC *pInBloc,
  3102. * BLOC *pOutBloc,
  3103. * BYTE *pFormat
  3104. * )
  3105. *
  3106. * Description : Encode une donne de type UTCTime.
  3107. * Suivant le format dtect, l'encodage consiste en :
  3108. * - sur 32 bits : le nombre de minutes ou de secondes depuis une
  3109. * date de rfrence.
  3110. * - sur 16 bits : le nombre de minutes de dcalage UTC
  3111. * s'il y a lieu.
  3112. *
  3113. * Remarks :
  3114. *
  3115. * In : pInBloc : la partie encoder (champ Content)
  3116. *
  3117. * Out : pOutBloc : l'encod (mmoire alloue ici librer par la
  3118. * fonction appelante)
  3119. * pFormat : indique au quel format tait la donne d'entre
  3120. *
  3121. * Responses : RV_SUCCESS : All is OK.
  3122. * RV_MALLOC_FAILED : Un malloc a chou.
  3123. * Autre : D'autres codes d'erreur peuvent tre retourns par des
  3124. * fonctions d'un niveau infrieur.
  3125. *
  3126. *******************************************************************************/
  3127. int CC_Encode_UTCTime(BLOC *pInBloc,
  3128. BLOC *pOutBloc,
  3129. BYTE *pFormat
  3130. )
  3131. {
  3132. BYTE
  3133. *pData;
  3134. ULONG
  3135. ulNbMinute,
  3136. ulNbSecond;
  3137. USHORT
  3138. usNbDeltaMinute,
  3139. usYear,
  3140. usMonth,
  3141. usDay,
  3142. usHour,
  3143. usMinute,
  3144. usSecond,
  3145. usDeltaHour,
  3146. usDeltaMinute,
  3147. usDayInYear;
  3148. pData = pInBloc->pData;
  3149. /* Calcul du nombre de minutes */
  3150. usYear = 10 * (pData[0] - '0') + (pData[1] - '0');
  3151. usMonth = 10 * (pData[2] - '0') + (pData[3] - '0');
  3152. usDay = 10 * (pData[4] - '0') + (pData[5] - '0');
  3153. usHour = 10 * (pData[6] - '0') + (pData[7] - '0');
  3154. usMinute = 10 * (pData[8] - '0') + (pData[9] - '0');
  3155. ASSERT((usYear >= 0) && (usYear <= 99));
  3156. ASSERT((usMonth >= 1) && (usMonth <= 12));
  3157. ASSERT((usDay >= 1) && (usDay <= 31));
  3158. ASSERT((usHour >= 0) && (usHour <= 23));
  3159. ASSERT((usMinute >= 0) && (usMinute <= 59));
  3160. /* Le nombre de jours dans l'ann�e vaut 0 le 1er janvier */
  3161. usDayInYear = NbDaysInMonth[usMonth - 1] + (usDay - 1);
  3162. if (((usYear % 4) == 0) && (usMonth >= 3)) usDayInYear++;
  3163. /* L'ann�e 00 est compt�e bissextile ci-dessous */
  3164. /* L'ann�e courante si elle l'est a d�j� �t� compt�e dans usDayInYear */
  3165. /*
  3166. Problme sur l'valuation de (usYear - 1) / 4 :
  3167. usYear = 8 -> 1
  3168. usYear = 4 -> 0
  3169. usYear = 0 -> 0 !!
  3170. ulNbMinute = usYear * UTCT_MINUTE_IN_YEAR
  3171. + (1 + (usYear - 1) / 4) * UTCT_MINUTE_IN_DAY
  3172. + usDayInYear * UTCT_MINUTE_IN_DAY
  3173. + usHour * UTCT_MINUTE_IN_HOUR
  3174. + usMinute;
  3175. */
  3176. ulNbMinute = usYear * UTCT_MINUTE_IN_YEAR
  3177. + (usYear + 3) / 4 * UTCT_MINUTE_IN_DAY // Ann�es bissextiles
  3178. + usDayInYear * UTCT_MINUTE_IN_DAY
  3179. + usHour * UTCT_MINUTE_IN_HOUR
  3180. + usMinute;
  3181. /* Le format et la suite des calculs en fonction de la longueur */
  3182. switch(pInBloc->usLen)
  3183. {
  3184. case 11 :
  3185. *pFormat = UTCT_YYMMDDhhmmZ;
  3186. ASSERT(pData[10] == 'Z');
  3187. pOutBloc->usLen = 4;
  3188. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  3189. {
  3190. return(RV_MALLOC_FAILED);
  3191. }
  3192. *(ULONG *)pOutBloc->pData = ulNbMinute;
  3193. break;
  3194. case 13 :
  3195. *pFormat = UTCT_YYMMDDhhmmssZ;
  3196. usSecond = 10 * (pData[10] - '0') + (pData[11] - '0');
  3197. ASSERT((usSecond >= 0) && (usSecond <= 59));
  3198. ASSERT(pData[12] == 'Z');
  3199. ulNbSecond = 60 * ulNbMinute + usSecond;
  3200. pOutBloc->usLen = 4;
  3201. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  3202. {
  3203. return(RV_MALLOC_FAILED);
  3204. }
  3205. *(ULONG *)pOutBloc->pData = ulNbSecond;
  3206. break;
  3207. case 15 :
  3208. if (pData[10] == '+')
  3209. {
  3210. *pFormat = UTCT_YYMMDDhhmmphhmm;
  3211. }
  3212. else if (pData[10] == '-')
  3213. {
  3214. *pFormat = UTCT_YYMMDDhhmmmhhmm;
  3215. }
  3216. else
  3217. {
  3218. return(RV_INVALID_DATA);
  3219. }
  3220. usDeltaHour = 10 * (pData[11] - '0') + (pData[12] - '0');
  3221. usDeltaMinute = 10 * (pData[13] - '0') + (pData[14] - '0');
  3222. ASSERT((usDeltaHour >= 0) && (usDeltaHour <= 23));
  3223. ASSERT((usDeltaMinute >= 0) && (usDeltaMinute <= 59));
  3224. usNbDeltaMinute = 60 * usDeltaHour + usDeltaMinute;
  3225. pOutBloc->usLen = 4 + 2;
  3226. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  3227. {
  3228. return(RV_MALLOC_FAILED);
  3229. }
  3230. *(ULONG *)pOutBloc->pData = ulNbMinute;
  3231. *(USHORT *)(pOutBloc->pData + sizeof(ulNbMinute)) = usNbDeltaMinute;
  3232. break;
  3233. case 17 :
  3234. if (pData[12] == '+')
  3235. {
  3236. *pFormat = UTCT_YYMMDDhhmmphhmm;
  3237. }
  3238. else if (pData[12] == '-')
  3239. {
  3240. *pFormat = UTCT_YYMMDDhhmmmhhmm;
  3241. }
  3242. else
  3243. {
  3244. return(RV_INVALID_DATA);
  3245. }
  3246. usSecond = 10 * (pData[10] - '0') + (pData[11] - '0');
  3247. ASSERT((usSecond >= 0) && (usSecond <= 59));
  3248. ulNbSecond = 60 * ulNbMinute + usSecond;
  3249. usDeltaHour = 10 * (pData[13] - '0') + (pData[14] - '0');
  3250. usDeltaMinute = 10 * (pData[15] - '0') + (pData[16] - '0');
  3251. ASSERT((usDeltaHour >= 0) && (usDeltaHour <= 23));
  3252. ASSERT((usDeltaMinute >= 0) && (usDeltaMinute <= 59));
  3253. usNbDeltaMinute = 60 * usDeltaHour + usDeltaMinute;
  3254. pOutBloc->usLen = 4 + 2;
  3255. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  3256. {
  3257. return(RV_MALLOC_FAILED);
  3258. }
  3259. *(ULONG *)pOutBloc->pData = ulNbSecond;
  3260. *(USHORT *)(pOutBloc->pData + sizeof(ulNbSecond)) = usNbDeltaMinute;
  3261. break;
  3262. default :
  3263. return(RV_INVALID_DATA);
  3264. }
  3265. return(RV_SUCCESS);
  3266. }
  3267. /*******************************************************************************
  3268. * int CC_Encode_SubjectPKInfo(BLOC *pInBloc,
  3269. * BLOC *pOutBloc
  3270. * )
  3271. *
  3272. * Description : Encode une donne de type SubjectPublicKeyInfo.
  3273. * Ceci consiste en l'clatement en ses diffrents composants,
  3274. * leurs dsenrobages Asn1 et leurs encodages respectifs, et la
  3275. * concatnation de ces rsultats.
  3276. *
  3277. * Remarks :
  3278. *
  3279. * In : pInBloc : la partie encoder (champ Content)
  3280. *
  3281. * Out : pOutBloc : l'encod (mmoire alloue ici librer par la
  3282. * fonction appelante)
  3283. *
  3284. * Responses : RV_SUCCESS : All is OK.
  3285. * RV_MALLOC_FAILED : Un malloc a chou.
  3286. * Autre : D'autres codes d'erreur peuvent tre retourns par des
  3287. * fonctions d'un niveau infrieur.
  3288. *
  3289. *******************************************************************************/
  3290. int CC_Encode_SubjectPKInfo(BLOC *pInBloc,
  3291. BLOC *pOutBloc
  3292. )
  3293. {
  3294. ASN1
  3295. algorithmPart,
  3296. subjectPKPart;
  3297. BLOC
  3298. algorithmEncoded,
  3299. subjectPKEncoded;
  3300. BYTE
  3301. // *pData,
  3302. *pCurrent;
  3303. int
  3304. rv;
  3305. /* D�composition du SubjectPKInfo en ses diff�rents composants */
  3306. pCurrent = pInBloc->pData;
  3307. algorithmPart.Asn1.pData = pCurrent;
  3308. rv = CC_ExtractContent(&algorithmPart);
  3309. if (rv != RV_SUCCESS) return rv;
  3310. pCurrent = algorithmPart.Content.pData + algorithmPart.Content.usLen;
  3311. subjectPKPart.Asn1.pData = pCurrent;
  3312. rv = CC_ExtractContent(&subjectPKPart);
  3313. if (rv != RV_SUCCESS) return rv;
  3314. pCurrent = subjectPKPart.Content.pData + subjectPKPart.Content.usLen;
  3315. /* Encodages des diff�rents composants et calcul de la longueur n�cessaire */
  3316. pOutBloc->usLen = 0;
  3317. rv = CC_Encode_AlgorithmIdentifier(&algorithmPart.Content, &algorithmEncoded);
  3318. if (rv != RV_SUCCESS) return rv;
  3319. pOutBloc->usLen += algorithmEncoded.usLen;
  3320. #ifdef _TRICKY_COMPRESSION
  3321. /* Ne pas faire le RawEncode permet de gagner l'octet 0xFF et �ventuellement plus */
  3322. #ifdef _OPT_HEADER
  3323. if (subjectPKPart.Content.usLen < 0x80)
  3324. {
  3325. if ((pData = GMEM_Alloc(pInBloc->usLen + 1)) == NULL_PTR)
  3326. {
  3327. return(RV_MALLOC_FAILED);
  3328. }
  3329. else
  3330. {
  3331. pData[0] = subjectPKPart.Content.usLen;
  3332. memcpy(&pData[1],
  3333. subjectPKPart.Content.pData,
  3334. subjectPKPart.Content.usLen);
  3335. subjectPKEncoded.usLen = subjectPKPart.Content.usLen + 1;
  3336. subjectPKEncoded.pData = pData;
  3337. }
  3338. pOutBloc->usLen += subjectPKEncoded.usLen;
  3339. }
  3340. else
  3341. {
  3342. if ((pData = GMEM_Alloc(pInBloc->usLen + 2)) == NULL_PTR)
  3343. {
  3344. return(RV_MALLOC_FAILED);
  3345. }
  3346. else
  3347. {
  3348. pData[0] = 0x80 | (subjectPKPart.Content.usLen >> 8);
  3349. pData[1] = subjectPKPart.Content.usLen & 0x00FF;
  3350. memcpy(&pData[2],
  3351. subjectPKPart.Content.pData,
  3352. subjectPKPart.Content.usLen);
  3353. subjectPKEncoded.usLen = subjectPKPart.Content.usLen + 2;
  3354. subjectPKEncoded.pData = pData;
  3355. }
  3356. pOutBloc->usLen += subjectPKEncoded.usLen;
  3357. }
  3358. #else /* _OPT_HEADER */
  3359. if ((pData = GMEM_Alloc(pInBloc->usLen + 2)) == NULL_PTR)
  3360. {
  3361. return(RV_MALLOC_FAILED);
  3362. }
  3363. else
  3364. {
  3365. pData[0] = subjectPKPart.Content.usLen >> 8;
  3366. pData[1] = subjectPKPart.Content.usLen & 0x00FF;
  3367. memcpy(&pData[2],
  3368. subjectPKPart.Content.pData,
  3369. subjectPKPart.Content.usLen);
  3370. subjectPKEncoded.usLen = subjectPKPart.Content.usLen + 2;
  3371. subjectPKEncoded.pData = pData;
  3372. }
  3373. pOutBloc->usLen += subjectPKEncoded.usLen;
  3374. #endif
  3375. #else /* _TRICKY_COMPRESSION */
  3376. rv = CC_RawEncode(&subjectPKPart.Content, &subjectPKEncoded, FALSE);
  3377. if (rv != RV_SUCCESS)
  3378. {
  3379. GMEM_Free(algorithmEncoded.pData);
  3380. return rv;
  3381. }
  3382. pOutBloc->usLen += subjectPKEncoded.usLen;
  3383. #endif
  3384. /* Reconstruction � partir des composants */
  3385. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  3386. {
  3387. GMEM_Free(algorithmEncoded.pData);
  3388. GMEM_Free(subjectPKEncoded.pData);
  3389. return(RV_MALLOC_FAILED);
  3390. }
  3391. pCurrent = pOutBloc->pData;
  3392. memcpy(pCurrent, algorithmEncoded.pData, algorithmEncoded.usLen);
  3393. GMEM_Free(algorithmEncoded.pData);
  3394. pCurrent += algorithmEncoded.usLen;
  3395. memcpy(pCurrent, subjectPKEncoded.pData, subjectPKEncoded.usLen);
  3396. GMEM_Free(subjectPKEncoded.pData);
  3397. pCurrent += subjectPKEncoded.usLen;
  3398. return(RV_SUCCESS);
  3399. }
  3400. /*******************************************************************************
  3401. * int CC_Encode_UniqueIdentifier(BLOC *pInBloc,
  3402. * BLOC *pOutBloc
  3403. * )
  3404. *
  3405. * Description : Encode une donne de type UniqueIdentifier.
  3406. * Ceci consiste seulement en l'encodage brute (CC_RawEncode) de la
  3407. * donne d'entre.
  3408. *
  3409. * Remarks :
  3410. *
  3411. * In : pInBloc : la partie encoder (champ Content)
  3412. *
  3413. * Out : pOutBloc : l'encod (mmoire alloue ici librer par la
  3414. * fonction appelante)
  3415. *
  3416. * Responses : RV_SUCCESS : All is OK.
  3417. * Autre : D'autres codes d'erreur peuvent tre retourns par des
  3418. * fonctions d'un niveau infrieur.
  3419. *
  3420. *******************************************************************************/
  3421. int CC_Encode_UniqueIdentifier(BLOC *pInBloc,
  3422. BLOC *pOutBloc
  3423. )
  3424. {
  3425. int
  3426. rv;
  3427. rv = CC_RawEncode(pInBloc, pOutBloc, TRUE);
  3428. if (rv != RV_SUCCESS) return rv;
  3429. return(RV_SUCCESS);
  3430. }
  3431. /*******************************************************************************
  3432. * int CC_Encode_Extensions(BLOC *pInBloc,
  3433. * BLOC *pOutBloc
  3434. * )
  3435. *
  3436. * Description : Encode une donne de type Extensions.
  3437. * Ceci consiste seulement en l'encodage brute (CC_RawEncode) de la
  3438. * donne d'entre.
  3439. *
  3440. * Remarks : Un dsenrobage supplmentaire (context specific) est requis.
  3441. * Un octet de contrle (en dbut du rsultat) indique le nombre
  3442. * de Extension dont est compos le Extensions.
  3443. *
  3444. * In : pInBloc : la partie encoder (champ Content)
  3445. *
  3446. * Out : pOutBloc : l'encod (mmoire alloue ici librer par la
  3447. * fonction appelante)
  3448. *
  3449. * Responses : RV_SUCCESS : All is OK.
  3450. * RV_MALLOC_FAILED : Un malloc a chou.
  3451. * Autre : D'autres codes d'erreur peuvent tre retourns par des
  3452. * fonctions d'un niveau infrieur.
  3453. *
  3454. *******************************************************************************/
  3455. int CC_Encode_Extensions(BLOC *pInBloc,
  3456. BLOC *pOutBloc
  3457. )
  3458. {
  3459. ASN1
  3460. ExtensionPart[MAX_EXTENSION],
  3461. InInAsn1;
  3462. BLOC
  3463. ExtensionEncoded[MAX_EXTENSION],
  3464. *pInInBloc;
  3465. BYTE
  3466. *pCurrent;
  3467. int
  3468. rv;
  3469. USHORT
  3470. i,
  3471. usNbExtension;
  3472. /* On enl�ve l'enrobage 'context specific' suppl�mentaire */
  3473. /* et on travaille avec pInInBloc au lieu de pInBloc */
  3474. InInAsn1.Asn1.pData = pInBloc->pData;
  3475. rv = CC_ExtractContent(&InInAsn1);
  3476. if (rv != RV_SUCCESS) return rv;
  3477. pInInBloc = &(InInAsn1.Content);
  3478. /* D�composition de Extensions en ses diff�rents Extension */
  3479. pCurrent = pInInBloc->pData;
  3480. usNbExtension = 0;
  3481. while (pCurrent < pInInBloc->pData + pInInBloc->usLen)
  3482. {
  3483. ExtensionPart[usNbExtension].Asn1.pData = pCurrent;
  3484. rv = CC_ExtractContent(&(ExtensionPart[usNbExtension]));
  3485. if (rv != RV_SUCCESS) return rv;
  3486. pCurrent = ExtensionPart[usNbExtension].Content.pData
  3487. + ExtensionPart[usNbExtension].Content.usLen;
  3488. usNbExtension++;
  3489. }
  3490. ASSERT(pCurrent == pInInBloc->pData + pInInBloc->usLen);
  3491. /* Encodages des diff�rents composants et calcul de la longueur n�cessaire */
  3492. for (i = 0; i < usNbExtension; i++)
  3493. {
  3494. ExtensionEncoded[i].pData = NULL;
  3495. }
  3496. pOutBloc->usLen = 1;
  3497. for (i = 0; i < usNbExtension; i++)
  3498. {
  3499. rv = CC_Encode_Extension(&ExtensionPart[i].Content, &ExtensionEncoded[i]);
  3500. if (rv != RV_SUCCESS) goto err;
  3501. pOutBloc->usLen += ExtensionEncoded[i].usLen;
  3502. }
  3503. /* Reconstruction � partir des composants */
  3504. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  3505. {
  3506. rv = RV_MALLOC_FAILED;
  3507. goto err;
  3508. }
  3509. pCurrent = pOutBloc->pData;
  3510. *pCurrent = (BYTE) usNbExtension;
  3511. pCurrent++;
  3512. for (i = 0; i < usNbExtension; i++)
  3513. {
  3514. memcpy(pCurrent, ExtensionEncoded[i].pData, ExtensionEncoded[i].usLen);
  3515. GMEM_Free(ExtensionEncoded[i].pData);
  3516. pCurrent += ExtensionEncoded[i].usLen;
  3517. }
  3518. return(RV_SUCCESS);
  3519. err:
  3520. for (i = 0; i < usNbExtension; i++)
  3521. {
  3522. GMEM_Free(ExtensionEncoded[i].pData);
  3523. }
  3524. return(rv);
  3525. }
  3526. /*******************************************************************************
  3527. * int CC_Encode_Extension(BLOC *pInBloc,
  3528. * BLOC *pOutBloc
  3529. * )
  3530. *
  3531. * Description : Encode une donne de type Extension.
  3532. * Ceci consiste seulement en l'encodage brute (CC_RawEncode) de la
  3533. * donne d'entre.
  3534. *
  3535. * Remarks :
  3536. *
  3537. * In : pInBloc : la partie encoder (champ Content)
  3538. *
  3539. * Out : pOutBloc : l'encod (mmoire alloue ici librer par la
  3540. * fonction appelante)
  3541. *
  3542. * Responses : RV_SUCCESS : All is OK.
  3543. * Autre : D'autres codes d'erreur peuvent tre retourns par des
  3544. * fonctions d'un niveau infrieur.
  3545. *
  3546. *******************************************************************************/
  3547. int CC_Encode_Extension(BLOC *pInBloc,
  3548. BLOC *pOutBloc
  3549. )
  3550. {
  3551. int
  3552. rv;
  3553. rv = CC_RawEncode(pInBloc, pOutBloc, TRUE);
  3554. if (rv != RV_SUCCESS) return rv;
  3555. return(RV_SUCCESS);
  3556. }
  3557. /*******************************************************************************
  3558. * int CC_Encode_Signature(BLOC *pInBloc,
  3559. * BLOC *pOutBloc
  3560. * )
  3561. *
  3562. * Description : Encode la signature du certificat.
  3563. * Ceci consiste seulement en l'encodage brute (CC_RawEncode) de la
  3564. * donne d'entre.
  3565. *
  3566. * Remarks : On peut viter de tenter de compresser (CC_RawEncode) si on
  3567. * estime que cela ne sera pas efficace (donne alatoire).
  3568. * Cela permet de gagner un octet (0xFF) pour les donnes de taille
  3569. * suprieure 30 octets (cas gnral).
  3570. *
  3571. * In : pInBloc : la partie encoder (champ Content)
  3572. *
  3573. * Out : pOutBloc : l'encod (mmoire alloue ici librer par la
  3574. * fonction appelante)
  3575. *
  3576. * Responses : RV_SUCCESS : All is OK.
  3577. * Autre : D'autres codes d'erreur peuvent tre retourns par des
  3578. * fonctions d'un niveau infrieur.
  3579. *
  3580. *******************************************************************************/
  3581. int CC_Encode_Signature(BLOC *pInBloc,
  3582. BLOC *pOutBloc
  3583. )
  3584. {
  3585. // BYTE
  3586. // *pData;
  3587. int
  3588. rv;
  3589. #ifdef _TRICKY_COMPRESSION
  3590. /* Ne pas faire le RawEncode permet de gagner l'octet 0xFF */
  3591. #ifdef _OPT_HEADER
  3592. if (pInBloc->usLen < 0x80)
  3593. {
  3594. if ((pData = GMEM_Alloc(pInBloc->usLen + 1)) == NULL_PTR)
  3595. {
  3596. return(RV_MALLOC_FAILED);
  3597. }
  3598. else
  3599. {
  3600. pData[0] = pInBloc->usLen;
  3601. memcpy(&pData[1], pInBloc->pData, pInBloc->usLen);
  3602. pOutBloc->usLen = pInBloc->usLen + 1;
  3603. pOutBloc->pData = pData;
  3604. }
  3605. }
  3606. else
  3607. {
  3608. if ((pData = GMEM_Alloc(pInBloc->usLen + 2)) == NULL_PTR)
  3609. {
  3610. return(RV_MALLOC_FAILED);
  3611. }
  3612. else
  3613. {
  3614. pData[0] = 0x80 | (pInBloc->usLen >> 8);
  3615. pData[1] = pInBloc->usLen & 0x00FF;
  3616. memcpy(&pData[2], pInBloc->pData, pInBloc->usLen);
  3617. pOutBloc->usLen = pInBloc->usLen + 2;
  3618. pOutBloc->pData = pData;
  3619. }
  3620. }
  3621. #else /* _OPT_HEADER */
  3622. if ((pData = GMEM_Alloc(pInBloc->usLen + 2)) == NULL_PTR)
  3623. {
  3624. return(RV_MALLOC_FAILED);
  3625. }
  3626. else
  3627. {
  3628. pData[0] = pInBloc->usLen >> 8;
  3629. pData[1] = pInBloc->usLen & 0x00FF;
  3630. memcpy(&pData[2], pInBloc->pData, pInBloc->usLen);
  3631. pOutBloc->usLen = pInBloc->usLen + 2;
  3632. pOutBloc->pData = pData;
  3633. }
  3634. #endif
  3635. #else /* _TRICKY_COMPRESSION */
  3636. rv = CC_RawEncode(pInBloc, pOutBloc, TRUE);
  3637. if (rv != RV_SUCCESS) return rv;
  3638. #endif
  3639. return(RV_SUCCESS);
  3640. }
  3641. /*******************************************************************************
  3642. * int CC_Decode_TBSCertificate(BYTE *pInData,
  3643. * BLOC *pOutBloc,
  3644. * USHORT *pLength
  3645. * )
  3646. *
  3647. * Description : Dcode une donne de type TBSCertificate.
  3648. * Ceci consiste en le dcodage des diffrentes parties encodes
  3649. * successives, leurs enrobages respectifs (tags uniquement
  3650. * par la spec X.509), et la concatnation de ces rsultats.
  3651. *
  3652. * Remarks :
  3653. *
  3654. * In : pInBloc : la partie dcoder (champ Content)
  3655. *
  3656. * Out : pOutBloc : le dcod (mmoire alloue ici librer par la
  3657. * fonction appelante)
  3658. * pLength : la longueur de donnes encods utilise
  3659. *
  3660. * Responses : RV_SUCCESS : All is OK.
  3661. * RV_MALLOC_FAILED : Un malloc a chou.
  3662. * Autre : D'autres codes d'erreur peuvent tre retourns par des
  3663. * fonctions d'un niveau infrieur.
  3664. *
  3665. *******************************************************************************/
  3666. int CC_Decode_TBSCertificate(BYTE *pInData,
  3667. BLOC *pOutBloc,
  3668. USHORT *pLength
  3669. )
  3670. {
  3671. ASN1
  3672. serialNumberPart,
  3673. signaturePart,
  3674. issuerPart,
  3675. validityPart,
  3676. subjectPart,
  3677. subjectPKInfoPart,
  3678. issuerUIDPart,
  3679. subjectUIDPart,
  3680. extensionsPart;
  3681. BOOL
  3682. bVersionPresent,
  3683. bIssuerUIDPresent,
  3684. bSubjectUIDPresent,
  3685. bExtensionsPresent;
  3686. BYTE
  3687. *pCurrent;
  3688. int
  3689. rv;
  3690. USHORT
  3691. usVersion = 0,
  3692. Length;
  3693. serialNumberPart.Asn1.pData = NULL;
  3694. signaturePart.Asn1.pData = NULL;
  3695. issuerPart.Asn1.pData = NULL;
  3696. validityPart.Asn1.pData = NULL;
  3697. subjectPart.Asn1.pData = NULL;
  3698. subjectPKInfoPart.Asn1.pData = NULL;
  3699. issuerUIDPart.Asn1.pData = NULL;
  3700. subjectUIDPart.Asn1.pData = NULL;
  3701. extensionsPart.Asn1.pData = NULL;
  3702. pCurrent = pInData;
  3703. bVersionPresent = ((*pCurrent & 0x80) != 0);
  3704. bIssuerUIDPresent = ((*pCurrent & 0x40) != 0);
  3705. bSubjectUIDPresent = ((*pCurrent & 0x20) != 0);
  3706. bExtensionsPresent = ((*pCurrent & 0x10) != 0);
  3707. usVersion = *pCurrent & 0x03;
  3708. pCurrent++;
  3709. rv = CC_Decode_CertificateSerialNumber(pCurrent, &(serialNumberPart.Content), &Length);
  3710. if (rv != RV_SUCCESS) goto err;
  3711. serialNumberPart.Tag = TAG_INTEGER;
  3712. rv = CC_BuildAsn1(&serialNumberPart);
  3713. GMEM_Free(serialNumberPart.Content.pData);
  3714. if (rv != RV_SUCCESS) goto err;
  3715. pCurrent += Length;
  3716. rv = CC_Decode_AlgorithmIdentifier(pCurrent, &(signaturePart.Content), &Length);
  3717. if (rv != RV_SUCCESS) goto err;
  3718. signaturePart.Tag = TAG_SEQUENCE;
  3719. rv = CC_BuildAsn1(&signaturePart);
  3720. GMEM_Free(signaturePart.Content.pData);
  3721. if (rv != RV_SUCCESS) goto err;
  3722. pCurrent += Length;
  3723. rv = CC_Decode_Name(pCurrent, &(issuerPart.Content), &Length);
  3724. if (rv != RV_SUCCESS) goto err;
  3725. issuerPart.Tag = TAG_SEQUENCE_OF;
  3726. rv = CC_BuildAsn1(&issuerPart);
  3727. GMEM_Free(issuerPart.Content.pData);
  3728. if (rv != RV_SUCCESS) goto err;
  3729. pCurrent += Length;
  3730. rv = CC_Decode_Validity(pCurrent, &(validityPart.Content), &Length);
  3731. if (rv != RV_SUCCESS) goto err;
  3732. validityPart.Tag = TAG_SEQUENCE;
  3733. rv = CC_BuildAsn1(&validityPart);
  3734. GMEM_Free(validityPart.Content.pData);
  3735. if (rv != RV_SUCCESS) goto err;
  3736. pCurrent += Length;
  3737. rv = CC_Decode_Name(pCurrent, &(subjectPart.Content), &Length);
  3738. if (rv != RV_SUCCESS) goto err;
  3739. subjectPart.Tag = TAG_SEQUENCE_OF;
  3740. rv = CC_BuildAsn1(&subjectPart);
  3741. GMEM_Free(subjectPart.Content.pData);
  3742. if (rv != RV_SUCCESS) goto err;
  3743. pCurrent += Length;
  3744. rv = CC_Decode_SubjectPKInfo(pCurrent, &(subjectPKInfoPart.Content), &Length);
  3745. if (rv != RV_SUCCESS) goto err;
  3746. subjectPKInfoPart.Tag = TAG_SEQUENCE;
  3747. rv = CC_BuildAsn1(&subjectPKInfoPart);
  3748. GMEM_Free(subjectPKInfoPart.Content.pData);
  3749. if (rv != RV_SUCCESS) goto err;
  3750. pCurrent += Length;
  3751. if (bIssuerUIDPresent == TRUE)
  3752. {
  3753. rv = CC_Decode_UniqueIdentifier(pCurrent, &(issuerUIDPart.Content), &Length);
  3754. if (rv != RV_SUCCESS) goto err;
  3755. issuerUIDPart.Tag = TAG_OPTION_ISSUER_UID;
  3756. rv = CC_BuildAsn1(&issuerUIDPart);
  3757. GMEM_Free(issuerUIDPart.Content.pData);
  3758. if (rv != RV_SUCCESS) goto err;
  3759. pCurrent += Length;
  3760. }
  3761. if (bSubjectUIDPresent == TRUE)
  3762. {
  3763. rv = CC_Decode_UniqueIdentifier(pCurrent, &(subjectUIDPart.Content), &Length);
  3764. if (rv != RV_SUCCESS) goto err;
  3765. subjectUIDPart.Tag = TAG_OPTION_SUBJECT_UID;
  3766. rv = CC_BuildAsn1(&subjectUIDPart);
  3767. GMEM_Free(subjectUIDPart.Content.pData);
  3768. if (rv != RV_SUCCESS) goto err;
  3769. pCurrent += Length;
  3770. }
  3771. if (bExtensionsPresent == TRUE)
  3772. {
  3773. rv = CC_Decode_Extensions(pCurrent, &(extensionsPart.Content), &Length);
  3774. if (rv != RV_SUCCESS) goto err;
  3775. extensionsPart.Tag = TAG_OPTION_EXTENSIONS;
  3776. rv = CC_BuildAsn1(&extensionsPart);
  3777. GMEM_Free(extensionsPart.Content.pData);
  3778. if (rv != RV_SUCCESS) goto err;
  3779. pCurrent += Length;
  3780. }
  3781. *pLength = (unsigned short)(DWORD) (pCurrent - pInData);
  3782. /* Calcul de la longueur du tbsCertificate d�cod� et allocation */
  3783. pOutBloc->usLen = (bVersionPresent ? 5 : 0)
  3784. + serialNumberPart.Asn1.usLen
  3785. + signaturePart.Asn1.usLen
  3786. + issuerPart.Asn1.usLen
  3787. + validityPart.Asn1.usLen
  3788. + subjectPart.Asn1.usLen
  3789. + subjectPKInfoPart.Asn1.usLen
  3790. + (bIssuerUIDPresent ? issuerUIDPart.Asn1.usLen : 0)
  3791. + (bSubjectUIDPresent ? subjectUIDPart.Asn1.usLen : 0)
  3792. + (bExtensionsPresent ? extensionsPart.Asn1.usLen : 0);
  3793. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  3794. {
  3795. rv = RV_MALLOC_FAILED;
  3796. goto err;
  3797. }
  3798. /* Reconstruction du tbsCertificate d�cod� */
  3799. pCurrent = pOutBloc->pData;
  3800. if (bVersionPresent == TRUE)
  3801. {
  3802. pCurrent[0] = TAG_OPTION_VERSION;
  3803. pCurrent[1] = 0x03;
  3804. pCurrent[2] = 0x02;
  3805. pCurrent[3] = 0x01;
  3806. pCurrent[4] = (BYTE)usVersion;
  3807. pCurrent += 5;
  3808. }
  3809. memcpy(pCurrent, serialNumberPart.Asn1.pData, serialNumberPart.Asn1.usLen);
  3810. GMEM_Free(serialNumberPart.Asn1.pData);
  3811. pCurrent += serialNumberPart.Asn1.usLen;
  3812. memcpy(pCurrent, signaturePart.Asn1.pData, signaturePart.Asn1.usLen);
  3813. GMEM_Free(signaturePart.Asn1.pData);
  3814. pCurrent += signaturePart.Asn1.usLen;
  3815. memcpy(pCurrent, issuerPart.Asn1.pData, issuerPart.Asn1.usLen);
  3816. GMEM_Free(issuerPart.Asn1.pData);
  3817. pCurrent += issuerPart.Asn1.usLen;
  3818. memcpy(pCurrent, validityPart.Asn1.pData, validityPart.Asn1.usLen);
  3819. GMEM_Free(validityPart.Asn1.pData);
  3820. pCurrent += validityPart.Asn1.usLen;
  3821. memcpy(pCurrent, subjectPart.Asn1.pData, subjectPart.Asn1.usLen);
  3822. GMEM_Free(subjectPart.Asn1.pData);
  3823. pCurrent += subjectPart.Asn1.usLen;
  3824. memcpy(pCurrent, subjectPKInfoPart.Asn1.pData, subjectPKInfoPart.Asn1.usLen);
  3825. GMEM_Free(subjectPKInfoPart.Asn1.pData);
  3826. pCurrent += subjectPKInfoPart.Asn1.usLen;
  3827. if (bIssuerUIDPresent == TRUE)
  3828. {
  3829. memcpy(pCurrent, issuerUIDPart.Asn1.pData, issuerUIDPart.Asn1.usLen);
  3830. GMEM_Free(issuerUIDPart.Asn1.pData);
  3831. pCurrent += issuerUIDPart.Asn1.usLen;
  3832. }
  3833. if (bSubjectUIDPresent == TRUE)
  3834. {
  3835. memcpy(pCurrent, subjectUIDPart.Asn1.pData, subjectUIDPart.Asn1.usLen);
  3836. GMEM_Free(subjectUIDPart.Asn1.pData);
  3837. pCurrent += subjectUIDPart.Asn1.usLen;
  3838. }
  3839. if (bExtensionsPresent == TRUE)
  3840. {
  3841. memcpy(pCurrent, extensionsPart.Asn1.pData, extensionsPart.Asn1.usLen);
  3842. GMEM_Free(extensionsPart.Asn1.pData);
  3843. pCurrent += extensionsPart.Asn1.usLen;
  3844. }
  3845. return(RV_SUCCESS);
  3846. err:
  3847. GMEM_Free(serialNumberPart.Asn1.pData);
  3848. GMEM_Free(signaturePart.Asn1.pData);
  3849. GMEM_Free(issuerPart.Asn1.pData);
  3850. GMEM_Free(validityPart.Asn1.pData);
  3851. GMEM_Free(subjectPart.Asn1.pData);
  3852. GMEM_Free(subjectPKInfoPart.Asn1.pData);
  3853. GMEM_Free(issuerUIDPart.Asn1.pData);
  3854. GMEM_Free(subjectUIDPart.Asn1.pData);
  3855. GMEM_Free(extensionsPart.Asn1.pData);
  3856. return (rv);
  3857. }
  3858. /*******************************************************************************
  3859. * int CC_Decode_CertificateSerialNumber(BYTE *pInData,
  3860. * BLOC *pOutBloc,
  3861. * USHORT *pLength
  3862. * )
  3863. *
  3864. * Description : Dcode une donne de type CertificateSerialNumber.
  3865. * Ceci consiste seulement en le dcodage brute (CC_RawDecode) de
  3866. * la donne d'entre.
  3867. *
  3868. * Remarks :
  3869. *
  3870. * In : pInBloc : la partie dcoder (champ Content)
  3871. *
  3872. * Out : pOutBloc : le dcod (mmoire alloue ici librer par la
  3873. * fonction appelante)
  3874. * pLength : la longueur de donnes encods utilise
  3875. *
  3876. * Responses : RV_SUCCESS : All is OK.
  3877. * RV_MALLOC_FAILED : Un malloc a chou.
  3878. * Autre : D'autres codes d'erreur peuvent tre retourns par des
  3879. * fonctions d'un niveau infrieur.
  3880. *
  3881. *******************************************************************************/
  3882. int CC_Decode_CertificateSerialNumber(BYTE *pInData,
  3883. BLOC *pOutBloc,
  3884. USHORT *pLength
  3885. )
  3886. {
  3887. int
  3888. rv;
  3889. rv = CC_RawDecode(pInData, pOutBloc, pLength, TRUE);
  3890. if (rv != RV_SUCCESS) return rv;
  3891. return(RV_SUCCESS);
  3892. }
  3893. /*******************************************************************************
  3894. * int CC_Decode_AlgorithmIdentifier(BYTE *pInData,
  3895. * BLOC *pOutBloc,
  3896. * USHORT *pLength
  3897. * )
  3898. *
  3899. * Description : Dcode une donne de type AlgorithmIdentifier.
  3900. * Ceci consiste en le dcodage des diffrentes parties encodes
  3901. * successives, leurs enrobages respectifs (tags uniquement
  3902. * par la spec X.509), et la concatnation de ces rsultats.
  3903. *
  3904. * Remarks : Voir l'encodage
  3905. *
  3906. * In : pInBloc : la partie dcoder (champ Content)
  3907. *
  3908. * Out : pOutBloc : le dcod (mmoire alloue ici librer par la
  3909. * fonction appelante)
  3910. * pLength : la longueur de donnes encods utilise
  3911. *
  3912. * Responses : RV_SUCCESS : All is OK.
  3913. * RV_MALLOC_FAILED : Un malloc a chou.
  3914. * Autre : D'autres codes d'erreur peuvent tre retourns par des
  3915. * fonctions d'un niveau infrieur.
  3916. *
  3917. *******************************************************************************/
  3918. int CC_Decode_AlgorithmIdentifier(BYTE *pInData,
  3919. BLOC *pOutBloc,
  3920. USHORT *pLength
  3921. )
  3922. {
  3923. ASN1
  3924. AlgorithmPart,
  3925. ParametersPart;
  3926. BOOL
  3927. bNullParam = FALSE,
  3928. bNoParam = FALSE;
  3929. int
  3930. rv;
  3931. USHORT
  3932. AlgoIndex,
  3933. Length;
  3934. AlgorithmPart.Asn1.pData = NULL;
  3935. ParametersPart.Asn1.pData = NULL;
  3936. if (pInData[0] == ESCAPE_CHAR)
  3937. {
  3938. rv = CC_RawDecode(&pInData[1], pOutBloc, &Length, TRUE);
  3939. *pLength = 1 + Length;
  3940. }
  3941. else
  3942. {
  3943. if (pInData[0] == ABSENT_PARAMETER_CHAR)
  3944. {
  3945. bNoParam = TRUE;
  3946. bNullParam = FALSE;
  3947. AlgoIndex = pInData[1];
  3948. }
  3949. else
  3950. {
  3951. bNoParam = ((pInData[0] & 0x80) != 0);
  3952. bNullParam = bNoParam;
  3953. AlgoIndex = pInData[0] & 0x7F;
  3954. }
  3955. if (bNoParam == TRUE)
  3956. {
  3957. AlgorithmPart.Content.usLen = (USHORT)strlen(AlgorithmTypeDict[AlgoIndex]);
  3958. if ((AlgorithmPart.Content.pData = GMEM_Alloc(AlgorithmPart.Content.usLen)) == NULL_PTR)
  3959. {
  3960. return (RV_MALLOC_FAILED);
  3961. }
  3962. memcpy(AlgorithmPart.Content.pData,
  3963. AlgorithmTypeDict[AlgoIndex],
  3964. AlgorithmPart.Content.usLen);
  3965. AlgorithmPart.Tag = TAG_OBJECT_IDENTIFIER;
  3966. rv = CC_BuildAsn1(&AlgorithmPart);
  3967. GMEM_Free(AlgorithmPart.Content.pData);
  3968. if (rv != RV_SUCCESS) goto err;
  3969. if (bNullParam == FALSE)
  3970. {
  3971. pOutBloc->usLen = AlgorithmPart.Asn1.usLen;
  3972. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  3973. {
  3974. rv = RV_MALLOC_FAILED;
  3975. goto err;
  3976. }
  3977. memcpy(pOutBloc->pData, AlgorithmPart.Asn1.pData, AlgorithmPart.Asn1.usLen);
  3978. *pLength = 2;
  3979. GMEM_Free(AlgorithmPart.Asn1.pData);
  3980. }
  3981. else
  3982. {
  3983. pOutBloc->usLen = AlgorithmPart.Asn1.usLen + 2;
  3984. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  3985. {
  3986. rv = RV_MALLOC_FAILED;
  3987. goto err;
  3988. }
  3989. memcpy(pOutBloc->pData, AlgorithmPart.Asn1.pData, AlgorithmPart.Asn1.usLen);
  3990. pOutBloc->pData[AlgorithmPart.Asn1.usLen] = 0x05;
  3991. pOutBloc->pData[AlgorithmPart.Asn1.usLen+1] = 0x00;
  3992. *pLength = 1;
  3993. GMEM_Free(AlgorithmPart.Asn1.pData);
  3994. }
  3995. }
  3996. else
  3997. {
  3998. AlgorithmPart.Content.usLen = (USHORT)strlen(AlgorithmTypeDict[AlgoIndex]);
  3999. if ((AlgorithmPart.Content.pData = GMEM_Alloc(AlgorithmPart.Content.usLen)) == NULL_PTR)
  4000. {
  4001. return (RV_MALLOC_FAILED);
  4002. }
  4003. memcpy(AlgorithmPart.Content.pData,
  4004. AlgorithmTypeDict[AlgoIndex],
  4005. AlgorithmPart.Content.usLen);
  4006. AlgorithmPart.Tag = TAG_OBJECT_IDENTIFIER;
  4007. rv = CC_BuildAsn1(&AlgorithmPart);
  4008. GMEM_Free(AlgorithmPart.Content.pData);
  4009. if (rv != RV_SUCCESS) goto err;
  4010. /* On recup�re directement l'asn1 des param�tres */
  4011. rv = CC_RawDecode(&pInData[1], &(ParametersPart.Asn1), &Length, TRUE);
  4012. if (rv != RV_SUCCESS) goto err;
  4013. pOutBloc->usLen = AlgorithmPart.Asn1.usLen + ParametersPart.Asn1.usLen;
  4014. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  4015. {
  4016. rv = RV_MALLOC_FAILED;
  4017. goto err;
  4018. }
  4019. memcpy(pOutBloc->pData,
  4020. AlgorithmPart.Asn1.pData,
  4021. AlgorithmPart.Asn1.usLen);
  4022. memcpy(pOutBloc->pData + AlgorithmPart.Asn1.usLen,
  4023. ParametersPart.Asn1.pData,
  4024. ParametersPart.Asn1.usLen);
  4025. *pLength = 1 + Length;
  4026. GMEM_Free(AlgorithmPart.Asn1.pData);
  4027. GMEM_Free(ParametersPart.Asn1.pData);
  4028. }
  4029. }
  4030. return (RV_SUCCESS);
  4031. err:
  4032. GMEM_Free(AlgorithmPart.Asn1.pData);
  4033. GMEM_Free(ParametersPart.Asn1.pData);
  4034. return rv;
  4035. }
  4036. /*******************************************************************************
  4037. * int CC_Decode_Name(BYTE *pInData,
  4038. * BLOC *pOutBloc,
  4039. * USHORT *pLength
  4040. * )
  4041. *
  4042. * Description : Dcode une donne de type Name.
  4043. * Ceci consiste en le dcodage des diffrentes parties encodes
  4044. * successives, leurs enrobages respectifs (tags uniquement
  4045. * par la spec X.509), et la concatnation de ces rsultats.
  4046. *
  4047. * Remarks : Voir l'encodage
  4048. *
  4049. * In : pInBloc : la partie dcoder (champ Content)
  4050. *
  4051. * Out : pOutBloc : le dcod (mmoire alloue ici librer par la
  4052. * fonction appelante)
  4053. * pLength : la longueur de donnes encods utilise
  4054. *
  4055. * Responses : RV_SUCCESS : All is OK.
  4056. * RV_MALLOC_FAILED : Un malloc a chou.
  4057. * Autre : D'autres codes d'erreur peuvent tre retourns par des
  4058. * fonctions d'un niveau infrieur.
  4059. *
  4060. *******************************************************************************/
  4061. int CC_Decode_Name(BYTE *pInData,
  4062. BLOC *pOutBloc,
  4063. USHORT *pLength
  4064. )
  4065. {
  4066. ASN1
  4067. RDN[MAX_RDN];
  4068. BYTE
  4069. *pCurrent;
  4070. int
  4071. rv;
  4072. USHORT
  4073. i,
  4074. usNbRDN,
  4075. Length;
  4076. /* D�codage des diff�rents composants et calcul de la longueur n�cessaire */
  4077. pCurrent = pInData;
  4078. pOutBloc->usLen = 0;
  4079. usNbRDN = (USHORT) *pCurrent;
  4080. pCurrent++;
  4081. for (i = 0; i < usNbRDN; i++)
  4082. {
  4083. RDN[i].Asn1.pData = NULL;
  4084. }
  4085. for (i = 0; i < usNbRDN; i++)
  4086. {
  4087. rv = CC_Decode_RDN(pCurrent, &(RDN[i].Content), &Length);
  4088. if (rv != RV_SUCCESS) goto err;
  4089. RDN[i].Tag = TAG_SET_OF;
  4090. rv = CC_BuildAsn1(&RDN[i]);
  4091. GMEM_Free(RDN[i].Content.pData);
  4092. if (rv != RV_SUCCESS) goto err;
  4093. pOutBloc->usLen += RDN[i].Asn1.usLen;
  4094. pCurrent += Length;
  4095. }
  4096. *pLength = (unsigned short)(DWORD) (pCurrent - pInData);
  4097. /* Reconstruction du Name d�cod� */
  4098. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  4099. {
  4100. rv = RV_MALLOC_FAILED;
  4101. goto err;
  4102. }
  4103. pCurrent = pOutBloc->pData;
  4104. for (i = 0; i < usNbRDN; i++)
  4105. {
  4106. memcpy(pCurrent, RDN[i].Asn1.pData, RDN[i].Asn1.usLen);
  4107. GMEM_Free(RDN[i].Asn1.pData);
  4108. pCurrent += RDN[i].Asn1.usLen;
  4109. }
  4110. return(RV_SUCCESS);
  4111. err:
  4112. for (i = 0; i < usNbRDN; i++)
  4113. {
  4114. GMEM_Free(RDN[i].Asn1.pData);
  4115. }
  4116. return rv;
  4117. }
  4118. /*******************************************************************************
  4119. * int CC_Decode_RDN(BYTE *pInData,
  4120. * BLOC *pOutBloc,
  4121. * USHORT *pLength
  4122. * )
  4123. *
  4124. * Description : Dcode une donne de type RelativeDistinguishedName.
  4125. * Ceci consiste en le dcodage des diffrentes parties encodes
  4126. * successives, leurs enrobages respectifs (tags uniquement
  4127. * par la spec X.509), et la concatnation de ces rsultats.
  4128. *
  4129. * Remarks : Voir l'encodage
  4130. *
  4131. * In : pInBloc : la partie dcoder (champ Content)
  4132. *
  4133. * Out : pOutBloc : le dcod (mmoire alloue ici librer par la
  4134. * fonction appelante)
  4135. * pLength : la longueur de donnes encods utilise
  4136. *
  4137. * Responses : RV_SUCCESS : All is OK.
  4138. * RV_MALLOC_FAILED : Un malloc a chou.
  4139. * Autre : D'autres codes d'erreur peuvent tre retourns par des
  4140. * fonctions d'un niveau infrieur.
  4141. *
  4142. *******************************************************************************/
  4143. int CC_Decode_RDN(BYTE *pInData,
  4144. BLOC *pOutBloc,
  4145. USHORT *pLength
  4146. )
  4147. {
  4148. ASN1
  4149. AVA[MAX_AVA];
  4150. BYTE
  4151. *pCurrent;
  4152. int
  4153. rv;
  4154. USHORT
  4155. i,
  4156. usNbAVA,
  4157. Length;
  4158. /* D�codage des diff�rents composants et calcul de la longueur n�cessaire */
  4159. pCurrent = pInData;
  4160. pOutBloc->usLen = 0;
  4161. usNbAVA = *pCurrent;
  4162. pCurrent++;
  4163. for (i = 0; i < usNbAVA; i++)
  4164. {
  4165. AVA[i].Asn1.pData = NULL;
  4166. }
  4167. for (i = 0; i < usNbAVA; i++)
  4168. {
  4169. rv = CC_Decode_AVA(pCurrent, &(AVA[i].Content), &Length);
  4170. if (rv != RV_SUCCESS) goto err;
  4171. AVA[i].Tag = TAG_SEQUENCE;
  4172. rv = CC_BuildAsn1(&AVA[i]);
  4173. GMEM_Free(AVA[i].Content.pData);
  4174. if (rv != RV_SUCCESS) goto err;
  4175. pOutBloc->usLen += AVA[i].Asn1.usLen;
  4176. pCurrent += Length;
  4177. }
  4178. *pLength = (unsigned short)(DWORD) (pCurrent - pInData);
  4179. /* Reconstruction du Name d�cod� */
  4180. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  4181. {
  4182. rv = RV_MALLOC_FAILED;
  4183. goto err;
  4184. }
  4185. pCurrent = pOutBloc->pData;
  4186. for (i = 0; i < usNbAVA; i++)
  4187. {
  4188. memcpy(pCurrent, AVA[i].Asn1.pData, AVA[i].Asn1.usLen);
  4189. GMEM_Free(AVA[i].Asn1.pData);
  4190. pCurrent += AVA[i].Asn1.usLen;
  4191. }
  4192. return(RV_SUCCESS);
  4193. err:
  4194. for (i = 0; i < usNbAVA; i++)
  4195. {
  4196. GMEM_Free(AVA[i].Asn1.pData);
  4197. }
  4198. return rv;
  4199. }
  4200. /*******************************************************************************
  4201. * int CC_Decode_AVA(BYTE *pInData,
  4202. * BLOC *pOutBloc,
  4203. * USHORT *pLength
  4204. * )
  4205. *
  4206. * Description : Dcode une donne de type AttributeValueAssertion.
  4207. * Ceci consiste en le dcodage des diffrentes parties encodes
  4208. * successives, leurs enrobages respectifs (tags uniquement
  4209. * par la spec X.509), et la concatnation de ces rsultats.
  4210. *
  4211. * Remarks : Voir l'encodage
  4212. *
  4213. * In : pInBloc : la partie dcoder (champ Content)
  4214. *
  4215. * Out : pOutBloc : le dcod (mmoire alloue ici librer par la
  4216. * fonction appelante)
  4217. * pLength : la longueur de donnes encods utilise
  4218. *
  4219. * Responses : RV_SUCCESS : All is OK.
  4220. * RV_MALLOC_FAILED : Un malloc a chou.
  4221. * Autre : D'autres codes d'erreur peuvent tre retourns par des
  4222. * fonctions d'un niveau infrieur.
  4223. *
  4224. *******************************************************************************/
  4225. int CC_Decode_AVA(BYTE *pInData,
  4226. BLOC *pOutBloc,
  4227. USHORT *pLength
  4228. )
  4229. {
  4230. ASN1
  4231. AttributeTypePart,
  4232. AttributeValuePart;
  4233. BYTE
  4234. *pCurrent;
  4235. int
  4236. rv;
  4237. USHORT
  4238. AttributeTypeIndex,
  4239. Length;
  4240. AttributeTypePart.Asn1.pData = NULL;
  4241. AttributeValuePart.Asn1.pData = NULL;
  4242. if (pInData[0] == ESCAPE_CHAR)
  4243. {
  4244. pCurrent = &pInData[1];
  4245. rv = CC_RawDecode(pCurrent, &(AttributeTypePart.Content), &Length, TRUE);
  4246. if (rv != RV_SUCCESS) goto err;
  4247. AttributeTypePart.Tag = TAG_OBJECT_IDENTIFIER;
  4248. rv = CC_BuildAsn1(&AttributeTypePart);
  4249. GMEM_Free(AttributeTypePart.Content.pData);
  4250. if (rv != RV_SUCCESS) goto err;
  4251. pCurrent += Length;
  4252. /* Ce que l'on d�code contient d�j� l'enrobage */
  4253. rv = CC_RawDecode(pCurrent, &(AttributeValuePart.Asn1), &Length, TRUE);
  4254. if (rv != RV_SUCCESS) goto err;
  4255. pCurrent += Length;
  4256. *pLength = (unsigned short)(DWORD) (pCurrent - pInData);
  4257. pOutBloc->usLen = AttributeTypePart.Asn1.usLen
  4258. + AttributeValuePart.Asn1.usLen;
  4259. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  4260. {
  4261. rv = RV_MALLOC_FAILED;
  4262. goto err;
  4263. }
  4264. pCurrent = pOutBloc->pData;
  4265. memcpy(pCurrent, AttributeTypePart.Asn1.pData, AttributeTypePart.Asn1.usLen);
  4266. GMEM_Free(AttributeTypePart.Asn1.pData);
  4267. pCurrent += AttributeTypePart.Asn1.usLen;
  4268. memcpy(pCurrent, AttributeValuePart.Asn1.pData, AttributeValuePart.Asn1.usLen);
  4269. GMEM_Free(AttributeValuePart.Asn1.pData);
  4270. pCurrent += AttributeValuePart.Asn1.usLen;
  4271. }
  4272. else
  4273. {
  4274. AttributeTypeIndex = pInData[0];
  4275. AttributeTypePart.Content.usLen = (USHORT)strlen(AttributeTypeDict[AttributeTypeIndex]);
  4276. if ((AttributeTypePart.Content.pData = GMEM_Alloc(AttributeTypePart.Content.usLen))
  4277. == NULL_PTR)
  4278. {
  4279. rv = RV_MALLOC_FAILED;
  4280. goto err;
  4281. }
  4282. memcpy(AttributeTypePart.Content.pData,
  4283. AttributeTypeDict[AttributeTypeIndex],
  4284. AttributeTypePart.Content.usLen);
  4285. AttributeTypePart.Tag = TAG_OBJECT_IDENTIFIER;
  4286. rv = CC_BuildAsn1(&AttributeTypePart);
  4287. GMEM_Free(AttributeTypePart.Content.pData);
  4288. if (rv != RV_SUCCESS) goto err;
  4289. rv = CC_RawDecode(&pInData[1], &(AttributeValuePart.Asn1), &Length, TRUE);
  4290. if (rv != RV_SUCCESS) goto err;
  4291. pOutBloc->usLen = AttributeTypePart.Asn1.usLen
  4292. + AttributeValuePart.Asn1.usLen;
  4293. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  4294. {
  4295. rv = RV_MALLOC_FAILED;
  4296. goto err;
  4297. }
  4298. pCurrent = pOutBloc->pData;
  4299. memcpy(pCurrent, AttributeTypePart.Asn1.pData, AttributeTypePart.Asn1.usLen);
  4300. GMEM_Free(AttributeTypePart.Asn1.pData);
  4301. pCurrent += AttributeTypePart.Asn1.usLen;
  4302. memcpy(pCurrent, AttributeValuePart.Asn1.pData, AttributeValuePart.Asn1.usLen);
  4303. GMEM_Free(AttributeValuePart.Asn1.pData);
  4304. pCurrent += AttributeValuePart.Asn1.usLen;
  4305. *pLength = 1 + Length;
  4306. }
  4307. return(RV_SUCCESS);
  4308. err:
  4309. GMEM_Free(AttributeTypePart.Asn1.pData);
  4310. GMEM_Free(AttributeValuePart.Asn1.pData);
  4311. return rv;
  4312. }
  4313. /*******************************************************************************
  4314. * int CC_Decode_Validity(BYTE *pInData,
  4315. * BLOC *pOutBloc,
  4316. * USHORT *pLength
  4317. * )
  4318. *
  4319. * Description : Dcode une donne de type Validity.
  4320. * Ceci consiste en le dcodage des diffrentes parties encodes
  4321. * successives, leurs enrobages respectifs (tags uniquement
  4322. * par la spec X.509), et la concatnation de ces rsultats.
  4323. *
  4324. * Remarks : Voir l'encodage
  4325. *
  4326. * In : pInBloc : la partie dcoder (champ Content)
  4327. *
  4328. * Out : pOutBloc : le dcod (mmoire alloue ici librer par la
  4329. * fonction appelante)
  4330. * pLength : la longueur de donnes encods utilise
  4331. *
  4332. * Responses : RV_SUCCESS : All is OK.
  4333. * RV_MALLOC_FAILED : Un malloc a chou.
  4334. * Autre : D'autres codes d'erreur peuvent tre retourns par des
  4335. * fonctions d'un niveau infrieur.
  4336. *
  4337. *******************************************************************************/
  4338. int CC_Decode_Validity(BYTE *pInData,
  4339. BLOC *pOutBloc,
  4340. USHORT *pLength
  4341. )
  4342. {
  4343. ASN1
  4344. notBeforePart,
  4345. notAfterPart;
  4346. BYTE
  4347. notBeforeFormat,
  4348. notAfterFormat,
  4349. *pCurrent;
  4350. int
  4351. rv;
  4352. USHORT
  4353. Length;
  4354. notBeforePart.Asn1.pData = NULL;
  4355. notAfterPart.Asn1.pData = NULL;
  4356. pCurrent = pInData;
  4357. notBeforeFormat = (*pCurrent & 0xF0) >> 4;
  4358. notAfterFormat = *pCurrent & 0x0F;
  4359. pCurrent++;
  4360. rv = CC_Decode_UTCTime(pCurrent, notBeforeFormat, &(notBeforePart.Content), &Length);
  4361. if (rv != RV_SUCCESS) goto err;
  4362. notBeforePart.Tag = TAG_UTCT;
  4363. rv = CC_BuildAsn1(&notBeforePart);
  4364. GMEM_Free(notBeforePart.Content.pData);
  4365. if (rv != RV_SUCCESS) goto err;
  4366. pCurrent += Length;
  4367. rv = CC_Decode_UTCTime(pCurrent, notAfterFormat, &(notAfterPart.Content), &Length);
  4368. if (rv != RV_SUCCESS) goto err;
  4369. notAfterPart.Tag = TAG_UTCT;
  4370. rv = CC_BuildAsn1(&notAfterPart);
  4371. GMEM_Free(notAfterPart.Content.pData);
  4372. if (rv != RV_SUCCESS) goto err;
  4373. pCurrent += Length;
  4374. *pLength = (unsigned short)(DWORD) (pCurrent - pInData);
  4375. /* Calcul de la longueur de Validity d�cod� et allocation */
  4376. pOutBloc->usLen = notBeforePart.Asn1.usLen
  4377. + notAfterPart.Asn1.usLen;
  4378. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  4379. {
  4380. rv = RV_MALLOC_FAILED;
  4381. goto err;
  4382. }
  4383. /* Reconstruction de Validity d�cod� */
  4384. pCurrent = pOutBloc->pData;
  4385. memcpy(pCurrent, notBeforePart.Asn1.pData, notBeforePart.Asn1.usLen);
  4386. GMEM_Free(notBeforePart.Asn1.pData);
  4387. pCurrent += notBeforePart.Asn1.usLen;
  4388. memcpy(pCurrent, notAfterPart.Asn1.pData, notAfterPart.Asn1.usLen);
  4389. GMEM_Free(notAfterPart.Asn1.pData);
  4390. pCurrent += notAfterPart.Asn1.usLen;
  4391. return(RV_SUCCESS);
  4392. err:
  4393. GMEM_Free(notBeforePart.Asn1.pData);
  4394. GMEM_Free(notAfterPart.Asn1.pData);
  4395. return rv;
  4396. }
  4397. /*******************************************************************************
  4398. * int CC_Decode_UTCTime(BYTE *pInData,
  4399. * BYTE Format,
  4400. * BLOC *pOutBloc,
  4401. * USHORT *pLength
  4402. * )
  4403. *
  4404. * Description : Dcode une donne de type UTCTime.
  4405. * Ceci consiste en la reconstruction de la chaine initiale suivant
  4406. * le format au quel elle tait exprime.
  4407. *
  4408. * Remarks : Voir l'encodage
  4409. *
  4410. * In : pInBloc : la partie dcoder (champ Content)
  4411. * Format : indique au quel format tait la donne d'entre
  4412. *
  4413. * Out : pOutBloc : le dcod (mmoire alloue ici librer par la
  4414. * fonction appelante)
  4415. * pLength : la longueur de donnes encods utilise
  4416. *
  4417. * Responses : RV_SUCCESS : All is OK.
  4418. * RV_MALLOC_FAILED : Un malloc a chou.
  4419. * RV_INVALID_DATA : Le format spcifi en entre est invalide.
  4420. *
  4421. *******************************************************************************/
  4422. int CC_Decode_UTCTime(BYTE *pInData,
  4423. BYTE Format,
  4424. BLOC *pOutBloc,
  4425. USHORT *pLength
  4426. )
  4427. {
  4428. BOOL
  4429. bBissextile = FALSE;
  4430. BYTE
  4431. *pCurrent;
  4432. ULONG
  4433. ulTime,
  4434. ulNbHour,
  4435. ulNbMinute;
  4436. USHORT
  4437. usNbDeltaMinute,
  4438. usNbDay,
  4439. usNbFourYears,
  4440. usNbDayInYear,
  4441. usYear,
  4442. usMonth,
  4443. usDay,
  4444. usHour,
  4445. usMinute,
  4446. usSecond,
  4447. usDeltaHour,
  4448. usDeltaMinute;
  4449. ulTime = *(ULONG UNALIGNED *)pInData; //memcpy( &ulTime, (ULONG *) &pInData[0],4);
  4450. switch(Format)
  4451. {
  4452. case UTCT_YYMMDDhhmmssZ :
  4453. case UTCT_YYMMDDhhmmssphhmm :
  4454. case UTCT_YYMMDDhhmmssmhhmm :
  4455. usSecond = (USHORT) (ulTime % 60);
  4456. ulNbMinute = ulTime / 60;
  4457. break;
  4458. default :
  4459. ulNbMinute = ulTime;
  4460. break;
  4461. }
  4462. switch(Format)
  4463. {
  4464. case UTCT_YYMMDDhhmmphhmm :
  4465. case UTCT_YYMMDDhhmmmhhmm :
  4466. case UTCT_YYMMDDhhmmssphhmm :
  4467. case UTCT_YYMMDDhhmmssmhhmm :
  4468. *pLength = 6;
  4469. usNbDeltaMinute = *(USHORT UNALIGNED *)&pInData[4]; //memcpy(&usNbDeltaMinute, (USHORT *) &pInData[4], 2);
  4470. ASSERT((usNbDeltaMinute >= 0) && (usNbDeltaMinute < 3600));
  4471. usDeltaMinute = usNbDeltaMinute % 60;
  4472. usDeltaHour = usNbDeltaMinute / 60;
  4473. break;
  4474. default :
  4475. *pLength = 4;
  4476. break;
  4477. }
  4478. usMinute = (USHORT) (ulNbMinute % 60);
  4479. ulNbHour = ulNbMinute / 60;
  4480. usHour = (USHORT) (ulNbHour % 24);
  4481. usNbDay = (USHORT) (ulNbHour / 24);
  4482. usNbFourYears = usNbDay / 1461;
  4483. usNbDay = usNbDay % 1461;
  4484. usYear = 4 * usNbFourYears;
  4485. if ((usNbDay >= 0) && (usNbDay <= 365))
  4486. {
  4487. bBissextile = TRUE;
  4488. usNbDayInYear = usNbDay;
  4489. }
  4490. if ((usNbDay >= 366) && (usNbDay <= 730))
  4491. {
  4492. usYear += 1;
  4493. usNbDayInYear = usNbDay - 366;
  4494. }
  4495. if ((usNbDay >= 731) && (usNbDay <= 1095))
  4496. {
  4497. usYear += 2;
  4498. usNbDayInYear = usNbDay - 731;
  4499. }
  4500. if ((usNbDay >= 1096) && (usNbDay <= 1460))
  4501. {
  4502. usYear += 3;
  4503. usNbDayInYear = usNbDay - 1096;
  4504. }
  4505. usMonth = 1;
  4506. while (usNbDayInYear >= (((usMonth >= 2) && (bBissextile)) ?
  4507. NbDaysInMonth[usMonth] + 1 :
  4508. NbDaysInMonth[usMonth]))
  4509. {
  4510. usMonth++;
  4511. }
  4512. usDay = usNbDayInYear - (((usMonth - 1 >= 2) && (bBissextile)) ?
  4513. NbDaysInMonth[usMonth - 1] + 1 :
  4514. NbDaysInMonth[usMonth - 1])
  4515. + 1;
  4516. switch(Format)
  4517. {
  4518. case UTCT_YYMMDDhhmmZ :
  4519. pOutBloc->usLen = 11;
  4520. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  4521. {
  4522. return(RV_MALLOC_FAILED);
  4523. }
  4524. pCurrent = pOutBloc->pData;
  4525. *pCurrent++ = '0' + usYear / 10;
  4526. *pCurrent++ = '0' + usYear % 10;
  4527. *pCurrent++ = '0' + usMonth / 10;
  4528. *pCurrent++ = '0' + usMonth % 10;
  4529. *pCurrent++ = '0' + usDay / 10;
  4530. *pCurrent++ = '0' + usDay % 10;
  4531. *pCurrent++ = '0' + usHour / 10;
  4532. *pCurrent++ = '0' + usHour % 10;
  4533. *pCurrent++ = '0' + usMinute / 10;
  4534. *pCurrent++ = '0' + usMinute % 10;
  4535. *pCurrent = 'Z';
  4536. break;
  4537. case UTCT_YYMMDDhhmmphhmm :
  4538. pOutBloc->usLen = 15;
  4539. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  4540. {
  4541. return(RV_MALLOC_FAILED);
  4542. }
  4543. pCurrent = pOutBloc->pData;
  4544. *pCurrent++ = '0' + usYear / 10;
  4545. *pCurrent++ = '0' + usYear % 10;
  4546. *pCurrent++ = '0' + usMonth / 10;
  4547. *pCurrent++ = '0' + usMonth % 10;
  4548. *pCurrent++ = '0' + usDay / 10;
  4549. *pCurrent++ = '0' + usDay % 10;
  4550. *pCurrent++ = '0' + usHour / 10;
  4551. *pCurrent++ = '0' + usHour % 10;
  4552. *pCurrent++ = '0' + usMinute / 10;
  4553. *pCurrent++ = '0' + usMinute % 10;
  4554. *pCurrent++ = '+';
  4555. *pCurrent++ = '0' + usDeltaHour / 10;
  4556. *pCurrent++ = '0' + usDeltaHour % 10;
  4557. *pCurrent++ = '0' + usDeltaMinute / 10;
  4558. *pCurrent++ = '0' + usDeltaMinute % 10;
  4559. break;
  4560. case UTCT_YYMMDDhhmmmhhmm :
  4561. pOutBloc->usLen = 15;
  4562. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  4563. {
  4564. return(RV_MALLOC_FAILED);
  4565. }
  4566. pCurrent = pOutBloc->pData;
  4567. *pCurrent++ = '0' + usYear / 10;
  4568. *pCurrent++ = '0' + usYear % 10;
  4569. *pCurrent++ = '0' + usMonth / 10;
  4570. *pCurrent++ = '0' + usMonth % 10;
  4571. *pCurrent++ = '0' + usDay / 10;
  4572. *pCurrent++ = '0' + usDay % 10;
  4573. *pCurrent++ = '0' + usHour / 10;
  4574. *pCurrent++ = '0' + usHour % 10;
  4575. *pCurrent++ = '0' + usMinute / 10;
  4576. *pCurrent++ = '0' + usMinute % 10;
  4577. *pCurrent++ = '-';
  4578. *pCurrent++ = '0' + usDeltaHour / 10;
  4579. *pCurrent++ = '0' + usDeltaHour % 10;
  4580. *pCurrent++ = '0' + usDeltaMinute / 10;
  4581. *pCurrent++ = '0' + usDeltaMinute % 10;
  4582. break;
  4583. case UTCT_YYMMDDhhmmssZ :
  4584. pOutBloc->usLen = 13;
  4585. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  4586. {
  4587. return(RV_MALLOC_FAILED);
  4588. }
  4589. pCurrent = pOutBloc->pData;
  4590. *pCurrent++ = '0' + usYear / 10;
  4591. *pCurrent++ = '0' + usYear % 10;
  4592. *pCurrent++ = '0' + usMonth / 10;
  4593. *pCurrent++ = '0' + usMonth % 10;
  4594. *pCurrent++ = '0' + usDay / 10;
  4595. *pCurrent++ = '0' + usDay % 10;
  4596. *pCurrent++ = '0' + usHour / 10;
  4597. *pCurrent++ = '0' + usHour % 10;
  4598. *pCurrent++ = '0' + usMinute / 10;
  4599. *pCurrent++ = '0' + usMinute % 10;
  4600. *pCurrent++ = '0' + usSecond / 10;
  4601. *pCurrent++ = '0' + usSecond % 10;
  4602. *pCurrent++ = 'Z';
  4603. break;
  4604. case UTCT_YYMMDDhhmmssphhmm :
  4605. pOutBloc->usLen = 17;
  4606. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  4607. {
  4608. return(RV_MALLOC_FAILED);
  4609. }
  4610. pCurrent = pOutBloc->pData;
  4611. *pCurrent++ = '0' + usYear / 10;
  4612. *pCurrent++ = '0' + usYear % 10;
  4613. *pCurrent++ = '0' + usMonth / 10;
  4614. *pCurrent++ = '0' + usMonth % 10;
  4615. *pCurrent++ = '0' + usDay / 10;
  4616. *pCurrent++ = '0' + usDay % 10;
  4617. *pCurrent++ = '0' + usHour / 10;
  4618. *pCurrent++ = '0' + usHour % 10;
  4619. *pCurrent++ = '0' + usMinute / 10;
  4620. *pCurrent++ = '0' + usMinute % 10;
  4621. *pCurrent++ = '0' + usSecond / 10;
  4622. *pCurrent++ = '0' + usSecond % 10;
  4623. *pCurrent++ = '+';
  4624. *pCurrent++ = '0' + usDeltaHour / 10;
  4625. *pCurrent++ = '0' + usDeltaHour % 10;
  4626. *pCurrent++ = '0' + usDeltaMinute / 10;
  4627. *pCurrent++ = '0' + usDeltaMinute % 10;
  4628. break;
  4629. case UTCT_YYMMDDhhmmssmhhmm :
  4630. pOutBloc->usLen = 17;
  4631. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  4632. {
  4633. return(RV_MALLOC_FAILED);
  4634. }
  4635. pCurrent = pOutBloc->pData;
  4636. *pCurrent++ = '0' + usYear / 10;
  4637. *pCurrent++ = '0' + usYear % 10;
  4638. *pCurrent++ = '0' + usMonth / 10;
  4639. *pCurrent++ = '0' + usMonth % 10;
  4640. *pCurrent++ = '0' + usDay / 10;
  4641. *pCurrent++ = '0' + usDay % 10;
  4642. *pCurrent++ = '0' + usHour / 10;
  4643. *pCurrent++ = '0' + usHour % 10;
  4644. *pCurrent++ = '0' + usMinute / 10;
  4645. *pCurrent++ = '0' + usMinute % 10;
  4646. *pCurrent++ = '0' + usSecond / 10;
  4647. *pCurrent++ = '0' + usSecond % 10;
  4648. *pCurrent++ = '-';
  4649. *pCurrent++ = '0' + usDeltaHour / 10;
  4650. *pCurrent++ = '0' + usDeltaHour % 10;
  4651. *pCurrent++ = '0' + usDeltaMinute / 10;
  4652. *pCurrent++ = '0' + usDeltaMinute % 10;
  4653. break;
  4654. default :
  4655. return(RV_INVALID_DATA);
  4656. break;
  4657. }
  4658. return(RV_SUCCESS);
  4659. }
  4660. /*******************************************************************************
  4661. * int CC_Decode_SubjectPKInfo(BYTE *pInData,
  4662. * BLOC *pOutBloc,
  4663. * USHORT *pLength
  4664. * )
  4665. *
  4666. * Description : Dcode une donne de type SubjectPublicKeyInfo.
  4667. * Ceci consiste en le dcodage des diffrentes parties encodes
  4668. * successives, leurs enrobages respectifs (tags uniquement
  4669. * par la spec X.509), et la concatnation de ces rsultats.
  4670. *
  4671. * Remarks : Voir l'encodage
  4672. *
  4673. * In : pInBloc : la partie dcoder (champ Content)
  4674. *
  4675. * Out : pOutBloc : le dcod (mmoire alloue ici librer par la
  4676. * fonction appelante)
  4677. * pLength : la longueur de donnes encods utilise
  4678. *
  4679. * Responses : RV_SUCCESS : All is OK.
  4680. * RV_MALLOC_FAILED : Un malloc a chou.
  4681. * Autre : D'autres codes d'erreur peuvent tre retourns par des
  4682. * fonctions d'un niveau infrieur.
  4683. *
  4684. *******************************************************************************/
  4685. int CC_Decode_SubjectPKInfo(BYTE *pInData,
  4686. BLOC *pOutBloc,
  4687. USHORT *pLength
  4688. )
  4689. {
  4690. ASN1
  4691. algorithmPart,
  4692. subjectPKPart;
  4693. // BLOC
  4694. // CompData;
  4695. BYTE
  4696. *pCurrent;
  4697. int
  4698. rv;
  4699. USHORT
  4700. Length;
  4701. algorithmPart.Asn1.pData = NULL;
  4702. subjectPKPart.Asn1.pData = NULL;
  4703. pCurrent = pInData;
  4704. rv = CC_Decode_AlgorithmIdentifier(pCurrent, &(algorithmPart.Content), &Length);
  4705. if (rv != RV_SUCCESS) goto err;
  4706. algorithmPart.Tag = TAG_SEQUENCE;
  4707. rv = CC_BuildAsn1(&algorithmPart);
  4708. GMEM_Free(algorithmPart.Content.pData);
  4709. if (rv != RV_SUCCESS) goto err;
  4710. pCurrent += Length;
  4711. #ifdef _TRICKY_COMPRESSION
  4712. /* Ne pas faire le RawDecode a permis de gagner l'octet 0xFF */
  4713. #ifdef _OPT_HEADER
  4714. if (pCurrent[0] < 0x80)
  4715. {
  4716. CompData.usLen = pCurrent[0];
  4717. CompData.pData = &(pCurrent[1]);
  4718. Length = CompData.usLen + 1;
  4719. }
  4720. else
  4721. {
  4722. CompData.usLen = ((pCurrent[0] & 0x7F) << 8) + pCurrent[1];
  4723. CompData.pData = &(pCurrent[2]);
  4724. Length = CompData.usLen + 2;
  4725. }
  4726. #else /* _OPT_HEADER */
  4727. CompData.usLen = (pCurrent[0] << 8) + pCurrent[1];
  4728. CompData.pData = &(pCurrent[2]);
  4729. Length = CompData.usLen + 2;
  4730. #endif
  4731. subjectPKPart.Content.usLen = CompData.usLen;
  4732. if ((subjectPKPart.Content.pData =
  4733. GMEM_Alloc(subjectPKPart.Content.usLen)) == NULL_PTR)
  4734. {
  4735. rv = RV_MALLOC_FAILED;
  4736. goto err;
  4737. }
  4738. memcpy(subjectPKPart.Content.pData,
  4739. CompData.pData,
  4740. subjectPKPart.Content.usLen
  4741. );
  4742. subjectPKPart.Tag = TAG_BIT_STRING;
  4743. rv = CC_BuildAsn1(&subjectPKPart);
  4744. GMEM_Free(subjectPKPart.Content.pData);
  4745. if (rv != RV_SUCCESS) goto err;
  4746. pCurrent += Length;
  4747. #else /* _TRICKY_COMPRESSION */
  4748. rv = CC_RawDecode(pCurrent, &(subjectPKPart.Content), &Length, FALSE);
  4749. if (rv != RV_SUCCESS) goto err;
  4750. subjectPKPart.Tag = TAG_BIT_STRING;
  4751. rv = CC_BuildAsn1(&subjectPKPart);
  4752. GMEM_Free(subjectPKPart.Content.pData);
  4753. if (rv != RV_SUCCESS) goto err;
  4754. pCurrent += Length;
  4755. #endif
  4756. *pLength = (unsigned short)(DWORD) (pCurrent - pInData);
  4757. /* Calcul de la longueur du d�cod� et allocation */
  4758. pOutBloc->usLen = algorithmPart.Asn1.usLen
  4759. + subjectPKPart.Asn1.usLen;
  4760. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  4761. {
  4762. rv = RV_MALLOC_FAILED;
  4763. goto err;
  4764. }
  4765. /* Reconstruction */
  4766. pCurrent = pOutBloc->pData;
  4767. memcpy(pCurrent, algorithmPart.Asn1.pData, algorithmPart.Asn1.usLen);
  4768. GMEM_Free(algorithmPart.Asn1.pData);
  4769. pCurrent += algorithmPart.Asn1.usLen;
  4770. memcpy(pCurrent, subjectPKPart.Asn1.pData, subjectPKPart.Asn1.usLen);
  4771. GMEM_Free(subjectPKPart.Asn1.pData);
  4772. pCurrent += subjectPKPart.Asn1.usLen;
  4773. return(RV_SUCCESS);
  4774. err:
  4775. GMEM_Free(algorithmPart.Asn1.pData);
  4776. GMEM_Free(subjectPKPart.Asn1.pData);
  4777. return rv;
  4778. }
  4779. /*******************************************************************************
  4780. * int CC_Decode_UniqueIdentifier(BYTE *pInData,
  4781. * BLOC *pOutBloc,
  4782. * USHORT *pLength
  4783. * )
  4784. *
  4785. * Description : Dcode une donne de type UniqueIdentifier.
  4786. * Ceci consiste seulement en le dcodage brute (CC_RawDecode) de
  4787. * la donne d'entre.
  4788. *
  4789. * Remarks :
  4790. *
  4791. * In : pInBloc : la partie dcoder (champ Content)
  4792. *
  4793. * Out : pOutBloc : le dcod (mmoire alloue ici librer par la
  4794. * fonction appelante)
  4795. *
  4796. * Responses : RV_SUCCESS : All is OK.
  4797. * RV_MALLOC_FAILED : Un malloc a chou.
  4798. * Autre : D'autres codes d'erreur peuvent tre retourns par des
  4799. * fonctions d'un niveau infrieur.
  4800. *
  4801. *******************************************************************************/
  4802. int CC_Decode_UniqueIdentifier(BYTE *pInData,
  4803. BLOC *pOutBloc,
  4804. USHORT *pLength
  4805. )
  4806. {
  4807. int
  4808. rv;
  4809. rv = CC_RawDecode(pInData, pOutBloc, pLength, TRUE);
  4810. if (rv != RV_SUCCESS) return rv;
  4811. return(RV_SUCCESS);
  4812. }
  4813. /*******************************************************************************
  4814. * int CC_Decode_Extensions(BYTE *pInData,
  4815. * BLOC *pOutBloc,
  4816. * USHORT *pLength
  4817. * )
  4818. *
  4819. * Description : Dcode une donne de type Extensions.
  4820. * Ceci consiste en le dcodage des diffrentes parties encodes
  4821. * successives, leurs enrobages respectifs (tags uniquement
  4822. * par la spec X.509), et la concatnation de ces rsultats.
  4823. *
  4824. * Remarks : Voir l'encodage
  4825. * L'ajout d'un enrobage 'context spcifique' est requis
  4826. *
  4827. * In : pInBloc : la partie dcoder (champ Content)
  4828. *
  4829. * Out : pOutBloc : le dcod (mmoire alloue ici librer par la
  4830. * fonction appelante)
  4831. * pLength : la longueur de donnes encods utilise
  4832. *
  4833. * Responses : RV_SUCCESS : All is OK.
  4834. * RV_MALLOC_FAILED : Un malloc a chou.
  4835. * Autre : D'autres codes d'erreur peuvent tre retourns par des
  4836. * fonctions d'un niveau infrieur.
  4837. *
  4838. *******************************************************************************/
  4839. int CC_Decode_Extensions(BYTE *pInData,
  4840. BLOC *pOutBloc,
  4841. USHORT *pLength
  4842. )
  4843. {
  4844. ASN1
  4845. ExtensionPart[MAX_AVA],
  4846. InOutAsn1;
  4847. BYTE
  4848. *pCurrent;
  4849. int
  4850. rv;
  4851. USHORT
  4852. i,
  4853. usNbExtension,
  4854. Length;
  4855. /* D�codage des diff�rents composants et calcul de la longueur n�cessaire */
  4856. pCurrent = pInData;
  4857. InOutAsn1.Content.usLen = 0;
  4858. usNbExtension = *pCurrent;
  4859. pCurrent++;
  4860. for (i = 0; i < usNbExtension; i++)
  4861. {
  4862. ExtensionPart[i].Asn1.pData = NULL;
  4863. }
  4864. for (i = 0; i < usNbExtension; i++)
  4865. {
  4866. rv = CC_Decode_Extension(pCurrent, &(ExtensionPart[i].Content), &Length);
  4867. if (rv != RV_SUCCESS) goto err;
  4868. ExtensionPart[i].Tag = TAG_SEQUENCE;
  4869. rv = CC_BuildAsn1(&ExtensionPart[i]);
  4870. GMEM_Free(ExtensionPart[i].Content.pData);
  4871. if (rv != RV_SUCCESS) goto err;
  4872. InOutAsn1.Content.usLen += ExtensionPart[i].Asn1.usLen;
  4873. pCurrent += Length;
  4874. }
  4875. *pLength = (unsigned short)(DWORD) (pCurrent - pInData);
  4876. /* Reconstruction de la partie int�rieure au 'context specific' */
  4877. if ((InOutAsn1.Content.pData = GMEM_Alloc(InOutAsn1.Content.usLen)) == NULL_PTR)
  4878. {
  4879. rv = RV_MALLOC_FAILED;
  4880. goto err;
  4881. }
  4882. pCurrent = InOutAsn1.Content.pData;
  4883. for (i = 0; i < usNbExtension; i++)
  4884. {
  4885. memcpy(pCurrent, ExtensionPart[i].Asn1.pData, ExtensionPart[i].Asn1.usLen);
  4886. GMEM_Free(ExtensionPart[i].Asn1.pData);
  4887. pCurrent += ExtensionPart[i].Asn1.usLen;
  4888. }
  4889. /* Ajout de l'enrobage 'context specific' */
  4890. InOutAsn1.Tag = TAG_SEQUENCE;
  4891. rv = CC_BuildAsn1(&InOutAsn1);
  4892. GMEM_Free(InOutAsn1.Content.pData);
  4893. if (rv != RV_SUCCESS) return rv;
  4894. *pOutBloc = InOutAsn1.Asn1;
  4895. return(RV_SUCCESS);
  4896. err:
  4897. for (i = 0; i < usNbExtension; i++)
  4898. {
  4899. GMEM_Free(ExtensionPart[i].Asn1.pData);
  4900. }
  4901. return rv;
  4902. }
  4903. /*******************************************************************************
  4904. * int CC_Decode_Extension(BYTE *pInData,
  4905. * BLOC *pOutBloc,
  4906. * USHORT *pLength
  4907. * )
  4908. *
  4909. * Description : Dcode une donne de type Extension.
  4910. * Ceci consiste seulement en le dcodage brute (CC_RawDecode) de
  4911. * la donne d'entre.
  4912. *
  4913. * Remarks :
  4914. *
  4915. * In : pInBloc : la partie dcoder (champ Content)
  4916. *
  4917. * Out : pOutBloc : le dcod (mmoire alloue ici librer par la
  4918. * fonction appelante)
  4919. *
  4920. * Responses : RV_SUCCESS : All is OK.
  4921. * RV_MALLOC_FAILED : Un malloc a chou.
  4922. * Autre : D'autres codes d'erreur peuvent tre retourns par des
  4923. * fonctions d'un niveau infrieur.
  4924. *
  4925. *******************************************************************************/
  4926. int CC_Decode_Extension(BYTE *pInData,
  4927. BLOC *pOutBloc,
  4928. USHORT *pLength
  4929. )
  4930. {
  4931. int
  4932. rv;
  4933. rv = CC_RawDecode(pInData, pOutBloc, pLength, TRUE);
  4934. if (rv != RV_SUCCESS) return rv;
  4935. return(RV_SUCCESS);
  4936. }
  4937. /*******************************************************************************
  4938. * int CC_Decode_Signature(BYTE *pInData,
  4939. * BLOC *pOutBloc,
  4940. * USHORT *pLength
  4941. * )
  4942. *
  4943. * Description : Dcode la signature du certificat.
  4944. * Ceci consiste seulement en le dcodage brute (CC_RawDecode) de
  4945. * la donne d'entre.
  4946. *
  4947. * Remarks : Voir l'encodage
  4948. *
  4949. * In : pInBloc : la partie dcoder (champ Content)
  4950. *
  4951. * Out : pOutBloc : le dcod (mmoire alloue ici librer par la
  4952. * fonction appelante)
  4953. *
  4954. * Responses : RV_SUCCESS : All is OK.
  4955. * RV_MALLOC_FAILED : Un malloc a chou.
  4956. * Autre : D'autres codes d'erreur peuvent tre retourns par des
  4957. * fonctions d'un niveau infrieur.
  4958. *
  4959. *******************************************************************************/
  4960. int CC_Decode_Signature(BYTE *pInData,
  4961. BLOC *pOutBloc,
  4962. USHORT *pLength
  4963. )
  4964. {
  4965. // BLOC
  4966. // CompData;
  4967. int
  4968. rv;
  4969. #ifdef _TRICKY_COMPRESSION
  4970. /* Ne pas faire le RawDecode a permis de gagner l'octet 0xFF */
  4971. #ifdef _OPT_HEADER
  4972. if (pInData[0] < 0x80)
  4973. {
  4974. CompData.usLen = pInData[0];
  4975. CompData.pData = &(pInData[1]);
  4976. *pLength = CompData.usLen + 1;
  4977. }
  4978. else
  4979. {
  4980. CompData.usLen = ((pInData[0] & 0x7F) << 8) + pInData[1];
  4981. CompData.pData = &(pInData[2]);
  4982. *pLength = CompData.usLen + 2;
  4983. }
  4984. #else /* _OPT_HEADER */
  4985. CompData.usLen = (pInData[0] << 8) + pInData[1];
  4986. CompData.pData = &(pInData[2]);
  4987. *pLength = CompData.usLen + 2;
  4988. #endif
  4989. pOutBloc->usLen = CompData.usLen;
  4990. if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR)
  4991. {
  4992. return(RV_MALLOC_FAILED);
  4993. }
  4994. memcpy(pOutBloc->pData, CompData.pData, pOutBloc->usLen);
  4995. #else /* _TRICKY_COMPRESSION */
  4996. rv = CC_RawDecode(pInData, pOutBloc, pLength, TRUE);
  4997. if (rv != RV_SUCCESS) return rv;
  4998. #endif
  4999. return(RV_SUCCESS);
  5000. }