Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2393 lines
71 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: ossfunc.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "global.hxx"
  11. extern "C"
  12. {
  13. #include "wtasn.h"
  14. }
  15. #include "crypttls.h"
  16. #include "unicode.h"
  17. #include "pkiasn1.h"
  18. #include <dbgdef.h>
  19. #include "locals.h"
  20. #define SpcAsnAlloc WVTNew
  21. #define SpcAsnFree WVTDelete
  22. // All the *pvInfo extra stuff needs to be aligned
  23. #define INFO_LEN_ALIGN(Len) ((Len + 7) & ~7)
  24. static const BYTE NullDer[2] = {0x05, 0x00};
  25. static const CRYPT_OBJID_BLOB NullDerBlob = {2, (BYTE *)&NullDer[0]};
  26. static HCRYPTASN1MODULE hAsn1Module;
  27. extern "C"
  28. {
  29. BOOL WINAPI WVTAsn1SpcLinkEncode(
  30. IN DWORD dwCertEncodingType,
  31. IN LPCSTR lpszStructType,
  32. IN PSPC_LINK pInfo,
  33. OUT BYTE *pbEncoded,
  34. IN OUT DWORD *pcbEncoded
  35. );
  36. BOOL WINAPI WVTAsn1SpcLinkDecode(
  37. IN DWORD dwCertEncodingType,
  38. IN LPCSTR lpszStructType,
  39. IN const BYTE *pbEncoded,
  40. IN DWORD cbEncoded,
  41. IN DWORD dwFlags,
  42. OUT PSPC_LINK pInfo,
  43. IN OUT DWORD *pcbInfo
  44. );
  45. BOOL WINAPI WVTAsn1SpcIndirectDataContentEncode(
  46. IN DWORD dwCertEncodingType,
  47. IN LPCSTR lpszStructType,
  48. IN PSPC_INDIRECT_DATA_CONTENT pInfo,
  49. OUT BYTE *pbEncoded,
  50. IN OUT DWORD *pcbEncoded
  51. );
  52. BOOL WINAPI WVTAsn1SpcIndirectDataContentDecode(
  53. IN DWORD dwCertEncodingType,
  54. IN LPCSTR lpszStructType,
  55. IN const BYTE *pbEncoded,
  56. IN DWORD cbEncoded,
  57. IN DWORD dwFlags,
  58. OUT PSPC_INDIRECT_DATA_CONTENT pInfo,
  59. IN OUT DWORD *pcbInfo
  60. );
  61. BOOL WINAPI WVTAsn1SpcSpAgencyInfoEncode(
  62. IN DWORD dwCertEncodingType,
  63. IN LPCSTR lpszStructType,
  64. IN PSPC_SP_AGENCY_INFO pInfo,
  65. OUT BYTE *pbEncoded,
  66. IN OUT DWORD *pcbEncoded
  67. );
  68. BOOL WINAPI WVTAsn1SpcSpAgencyInfoDecode(
  69. IN DWORD dwCertEncodingType,
  70. IN LPCSTR lpszStructType,
  71. IN const BYTE *pbEncoded,
  72. IN DWORD cbEncoded,
  73. IN DWORD dwFlags,
  74. OUT PSPC_SP_AGENCY_INFO pInfo,
  75. IN OUT DWORD *pcbInfo
  76. );
  77. BOOL WINAPI WVTAsn1SpcMinimalCriteriaInfoEncode(
  78. IN DWORD dwCertEncodingType,
  79. IN LPCSTR lpszStructType,
  80. IN BOOL *pInfo,
  81. OUT BYTE *pbEncoded,
  82. IN OUT DWORD *pcbEncoded
  83. );
  84. BOOL WINAPI WVTAsn1SpcMinimalCriteriaInfoDecode(
  85. IN DWORD dwCertEncodingType,
  86. IN LPCSTR lpszStructType,
  87. IN const BYTE *pbEncoded,
  88. IN DWORD cbEncoded,
  89. IN DWORD dwFlags,
  90. OUT BOOL *pInfo,
  91. IN OUT DWORD *pcbInfo
  92. );
  93. BOOL WINAPI WVTAsn1SpcFinancialCriteriaInfoEncode(
  94. IN DWORD dwCertEncodingType,
  95. IN LPCSTR lpszStructType,
  96. IN PSPC_FINANCIAL_CRITERIA pInfo,
  97. OUT BYTE *pbEncoded,
  98. IN OUT DWORD *pcbEncoded
  99. );
  100. BOOL WINAPI WVTAsn1SpcFinancialCriteriaInfoDecode(
  101. IN DWORD dwCertEncodingType,
  102. IN LPCSTR lpszStructType,
  103. IN const BYTE *pbEncoded,
  104. IN DWORD cbEncoded,
  105. IN DWORD dwFlags,
  106. OUT PSPC_FINANCIAL_CRITERIA pInfo,
  107. IN OUT DWORD *pcbInfo
  108. );
  109. BOOL WINAPI WVTAsn1SpcStatementTypeEncode(
  110. IN DWORD dwCertEncodingType,
  111. IN LPCSTR lpszStructType,
  112. IN PSPC_STATEMENT_TYPE pInfo,
  113. OUT BYTE *pbEncoded,
  114. IN OUT DWORD *pcbEncoded
  115. );
  116. BOOL WINAPI WVTAsn1SpcStatementTypeDecode(
  117. IN DWORD dwCertEncodingType,
  118. IN LPCSTR lpszStructType,
  119. IN const BYTE *pbEncoded,
  120. IN DWORD cbEncoded,
  121. IN DWORD dwFlags,
  122. OUT PSPC_STATEMENT_TYPE pInfo,
  123. IN OUT DWORD *pcbInfo
  124. );
  125. BOOL WINAPI WVTAsn1SpcSpOpusInfoEncode(
  126. IN DWORD dwCertEncodingType,
  127. IN LPCSTR lpszStructType,
  128. IN PSPC_SP_OPUS_INFO pInfo,
  129. OUT BYTE *pbEncoded,
  130. IN OUT DWORD *pcbEncoded
  131. );
  132. BOOL WINAPI WVTAsn1SpcSpOpusInfoDecode(
  133. IN DWORD dwCertEncodingType,
  134. IN LPCSTR lpszStructType,
  135. IN const BYTE *pbEncoded,
  136. IN DWORD cbEncoded,
  137. IN DWORD dwFlags,
  138. OUT PSPC_SP_OPUS_INFO pInfo,
  139. IN OUT DWORD *pcbInfo
  140. );
  141. BOOL WINAPI WVTAsn1SpcPeImageDataEncode(
  142. IN DWORD dwCertEncodingType,
  143. IN LPCSTR lpszStructType,
  144. IN PSPC_PE_IMAGE_DATA pInfo,
  145. OUT BYTE *pbEncoded,
  146. IN OUT DWORD *pcbEncoded
  147. );
  148. BOOL WINAPI WVTAsn1SpcPeImageDataDecode(
  149. IN DWORD dwCertEncodingType,
  150. IN LPCSTR lpszStructType,
  151. IN const BYTE *pbEncoded,
  152. IN DWORD cbEncoded,
  153. IN DWORD dwFlags,
  154. OUT PSPC_PE_IMAGE_DATA pInfo,
  155. IN OUT DWORD *pcbInfo
  156. );
  157. BOOL WINAPI WVTAsn1SpcSigInfoEncode(
  158. IN DWORD dwCertEncodingType,
  159. IN LPCSTR lpszStructType,
  160. IN PSPC_SIGINFO pInfo,
  161. OUT BYTE *pbEncoded,
  162. IN OUT DWORD *pcbEncoded
  163. );
  164. BOOL WINAPI WVTAsn1SpcSigInfoDecode(
  165. IN DWORD dwCertEncodingType,
  166. IN LPCSTR lpszStructType,
  167. IN const BYTE *pbEncoded,
  168. IN DWORD cbEncoded,
  169. IN DWORD dwFlags,
  170. OUT PSPC_SIGINFO pInfo,
  171. IN OUT DWORD *pcbInfo
  172. );
  173. BOOL WINAPI WVTAsn1UtcTimeDecode(
  174. IN DWORD dwCertEncodingType,
  175. IN LPCSTR lpszStructType,
  176. IN const BYTE *pbEncoded,
  177. IN DWORD cbEncoded,
  178. IN DWORD dwFlags,
  179. OUT FILETIME * pFileTime,
  180. IN OUT DWORD *pcbFileTime
  181. );
  182. BOOL WINAPI WVTAsn1CatNameValueEncode(
  183. IN DWORD dwCertEncodingType,
  184. IN LPCSTR lpszStructType,
  185. IN PCAT_NAMEVALUE pInfo,
  186. OUT BYTE *pbEncoded,
  187. IN OUT DWORD *pcbEncoded);
  188. BOOL WINAPI WVTAsn1CatMemberInfoEncode(
  189. IN DWORD dwEncoding,
  190. IN LPCSTR lpszStructType,
  191. IN PCAT_MEMBERINFO pInfo,
  192. OUT BYTE *pbEncoded,
  193. IN OUT DWORD *pcbEncoded);
  194. BOOL WINAPI WVTAsn1CatNameValueDecode(
  195. IN DWORD dwCertEncodingType,
  196. IN LPCSTR lpszStructType,
  197. IN const BYTE *pbEncoded,
  198. IN DWORD cbEncoded,
  199. IN DWORD dwFlags,
  200. OUT PCAT_NAMEVALUE pInfo,
  201. IN OUT DWORD *pcbInfo);
  202. BOOL WINAPI WVTAsn1CatMemberInfoDecode(
  203. IN DWORD dwCertEncodingType,
  204. IN LPCSTR lpszStructType,
  205. IN const BYTE *pbEncoded,
  206. IN DWORD cbEncoded,
  207. IN DWORD dwFlags,
  208. OUT PCAT_MEMBERINFO pInfo,
  209. IN OUT DWORD *pcbInfo);
  210. };
  211. static inline ASN1encoding_t GetEncoder(void)
  212. {
  213. return I_CryptGetAsn1Encoder(hAsn1Module);
  214. }
  215. static inline ASN1decoding_t GetDecoder(void)
  216. {
  217. return I_CryptGetAsn1Decoder(hAsn1Module);
  218. }
  219. //+-------------------------------------------------------------------------
  220. // SPC ASN allocation and free functions
  221. //--------------------------------------------------------------------------
  222. HRESULT HError()
  223. {
  224. DWORD dw = GetLastError();
  225. HRESULT hr;
  226. if ( dw <= 0xFFFF )
  227. hr = HRESULT_FROM_WIN32 ( dw );
  228. else
  229. hr = dw;
  230. if ( ! FAILED ( hr ) )
  231. {
  232. // somebody failed a call without properly setting an error condition
  233. hr = E_UNEXPECTED;
  234. }
  235. return hr;
  236. }
  237. typedef struct _OID_REG_ENTRY {
  238. LPCSTR pszOID;
  239. LPCSTR pszOverrideFuncName;
  240. } OID_REG_ENTRY, *POID_REG_ENTRY;
  241. static const OID_REG_ENTRY SpcRegEncodeTable[] =
  242. {
  243. SPC_PE_IMAGE_DATA_OBJID, "WVTAsn1SpcPeImageDataEncode",
  244. SPC_PE_IMAGE_DATA_STRUCT, "WVTAsn1SpcPeImageDataEncode",
  245. SPC_CAB_DATA_OBJID, "WVTAsn1SpcLinkEncode",
  246. SPC_CAB_DATA_STRUCT, "WVTAsn1SpcLinkEncode",
  247. SPC_JAVA_CLASS_DATA_OBJID, "WVTAsn1SpcLinkEncode",
  248. SPC_JAVA_CLASS_DATA_STRUCT, "WVTAsn1SpcLinkEncode",
  249. SPC_LINK_OBJID, "WVTAsn1SpcLinkEncode",
  250. SPC_LINK_STRUCT, "WVTAsn1SpcLinkEncode",
  251. SPC_SIGINFO_OBJID, "WVTAsn1SpcSigInfoEncode",
  252. SPC_SIGINFO_STRUCT, "WVTAsn1SpcSigInfoEncode",
  253. SPC_INDIRECT_DATA_OBJID, "WVTAsn1SpcIndirectDataContentEncode",
  254. SPC_INDIRECT_DATA_CONTENT_STRUCT, "WVTAsn1SpcIndirectDataContentEncode",
  255. SPC_SP_AGENCY_INFO_OBJID, "WVTAsn1SpcSpAgencyInfoEncode",
  256. SPC_SP_AGENCY_INFO_STRUCT, "WVTAsn1SpcSpAgencyInfoEncode",
  257. SPC_MINIMAL_CRITERIA_OBJID, "WVTAsn1SpcMinimalCriteriaInfoEncode",
  258. SPC_MINIMAL_CRITERIA_STRUCT, "WVTAsn1SpcMinimalCriteriaInfoEncode",
  259. SPC_FINANCIAL_CRITERIA_OBJID, "WVTAsn1SpcFinancialCriteriaInfoEncode",
  260. SPC_FINANCIAL_CRITERIA_STRUCT, "WVTAsn1SpcFinancialCriteriaInfoEncode",
  261. SPC_STATEMENT_TYPE_OBJID, "WVTAsn1SpcStatementTypeEncode",
  262. SPC_STATEMENT_TYPE_STRUCT, "WVTAsn1SpcStatementTypeEncode",
  263. CAT_NAMEVALUE_OBJID, "WVTAsn1CatNameValueEncode",
  264. CAT_NAMEVALUE_STRUCT, "WVTAsn1CatNameValueEncode",
  265. CAT_MEMBERINFO_OBJID, "WVTAsn1CatMemberInfoEncode",
  266. CAT_MEMBERINFO_STRUCT, "WVTAsn1CatMemberInfoEncode",
  267. SPC_SP_OPUS_INFO_OBJID, "WVTAsn1SpcSpOpusInfoEncode",
  268. SPC_SP_OPUS_INFO_STRUCT, "WVTAsn1SpcSpOpusInfoEncode"
  269. };
  270. #define SPC_REG_ENCODE_COUNT (sizeof(SpcRegEncodeTable) / sizeof(SpcRegEncodeTable[0]))
  271. static const OID_REG_ENTRY SpcRegDecodeTable[] =
  272. {
  273. SPC_PE_IMAGE_DATA_OBJID, "WVTAsn1SpcPeImageDataDecode",
  274. SPC_PE_IMAGE_DATA_STRUCT, "WVTAsn1SpcPeImageDataDecode",
  275. SPC_CAB_DATA_OBJID, "WVTAsn1SpcLinkDecode",
  276. SPC_CAB_DATA_STRUCT, "WVTAsn1SpcLinkDecode",
  277. SPC_JAVA_CLASS_DATA_OBJID, "WVTAsn1SpcLinkDecode",
  278. SPC_JAVA_CLASS_DATA_STRUCT, "WVTAsn1SpcLinkDecode",
  279. SPC_LINK_OBJID, "WVTAsn1SpcLinkDecode",
  280. SPC_LINK_STRUCT, "WVTAsn1SpcLinkDecode",
  281. SPC_SIGINFO_OBJID, "WVTAsn1SpcSigInfoDecode",
  282. SPC_SIGINFO_STRUCT, "WVTAsn1SpcSigInfoDecode",
  283. SPC_INDIRECT_DATA_OBJID, "WVTAsn1SpcIndirectDataContentDecode",
  284. SPC_INDIRECT_DATA_CONTENT_STRUCT, "WVTAsn1SpcIndirectDataContentDecode",
  285. SPC_SP_AGENCY_INFO_OBJID, "WVTAsn1SpcSpAgencyInfoDecode",
  286. SPC_SP_AGENCY_INFO_STRUCT, "WVTAsn1SpcSpAgencyInfoDecode",
  287. SPC_MINIMAL_CRITERIA_OBJID, "WVTAsn1SpcMinimalCriteriaInfoDecode",
  288. SPC_MINIMAL_CRITERIA_STRUCT, "WVTAsn1SpcMinimalCriteriaInfoDecode",
  289. SPC_FINANCIAL_CRITERIA_OBJID, "WVTAsn1SpcFinancialCriteriaInfoDecode",
  290. SPC_FINANCIAL_CRITERIA_STRUCT, "WVTAsn1SpcFinancialCriteriaInfoDecode",
  291. SPC_STATEMENT_TYPE_OBJID, "WVTAsn1SpcStatementTypeDecode",
  292. SPC_STATEMENT_TYPE_STRUCT, "WVTAsn1SpcStatementTypeDecode",
  293. CAT_NAMEVALUE_OBJID, "WVTAsn1CatNameValueDecode",
  294. CAT_NAMEVALUE_STRUCT, "WVTAsn1CatNameValueDecode",
  295. CAT_MEMBERINFO_OBJID, "WVTAsn1CatMemberInfoDecode",
  296. CAT_MEMBERINFO_STRUCT, "WVTAsn1CatMemberInfoDecode",
  297. SPC_SP_OPUS_INFO_OBJID, "WVTAsn1SpcSpOpusInfoDecode",
  298. SPC_SP_OPUS_INFO_STRUCT, "WVTAsn1SpcSpOpusInfoDecode"
  299. };
  300. #define SPC_REG_DECODE_COUNT (sizeof(SpcRegDecodeTable) / sizeof(SpcRegDecodeTable[0]))
  301. #define ASN1_OID_OFFSET
  302. #define ASN1_OID_PREFIX
  303. static const CRYPT_OID_FUNC_ENTRY SpcEncodeFuncTable[] =
  304. {
  305. ASN1_OID_OFFSET SPC_PE_IMAGE_DATA_STRUCT, WVTAsn1SpcPeImageDataEncode,
  306. ASN1_OID_PREFIX SPC_PE_IMAGE_DATA_OBJID, WVTAsn1SpcPeImageDataEncode,
  307. ASN1_OID_PREFIX SPC_CAB_DATA_OBJID, WVTAsn1SpcLinkEncode,
  308. ASN1_OID_OFFSET SPC_CAB_DATA_STRUCT, WVTAsn1SpcLinkEncode,
  309. ASN1_OID_OFFSET SPC_LINK_STRUCT, WVTAsn1SpcLinkEncode,
  310. ASN1_OID_PREFIX SPC_LINK_OBJID, WVTAsn1SpcLinkEncode,
  311. ASN1_OID_OFFSET SPC_SIGINFO_STRUCT, WVTAsn1SpcSigInfoEncode,
  312. ASN1_OID_PREFIX SPC_SIGINFO_OBJID, WVTAsn1SpcSigInfoEncode,
  313. ASN1_OID_PREFIX SPC_INDIRECT_DATA_OBJID, WVTAsn1SpcIndirectDataContentEncode,
  314. ASN1_OID_OFFSET SPC_INDIRECT_DATA_CONTENT_STRUCT, WVTAsn1SpcIndirectDataContentEncode,
  315. ASN1_OID_OFFSET SPC_SP_AGENCY_INFO_STRUCT, WVTAsn1SpcSpAgencyInfoEncode,
  316. ASN1_OID_PREFIX SPC_SP_AGENCY_INFO_OBJID, WVTAsn1SpcSpAgencyInfoEncode,
  317. ASN1_OID_OFFSET SPC_MINIMAL_CRITERIA_STRUCT, WVTAsn1SpcMinimalCriteriaInfoEncode,
  318. ASN1_OID_PREFIX SPC_MINIMAL_CRITERIA_OBJID, WVTAsn1SpcMinimalCriteriaInfoEncode,
  319. ASN1_OID_OFFSET SPC_FINANCIAL_CRITERIA_STRUCT, WVTAsn1SpcFinancialCriteriaInfoEncode,
  320. ASN1_OID_PREFIX SPC_FINANCIAL_CRITERIA_OBJID, WVTAsn1SpcFinancialCriteriaInfoEncode,
  321. ASN1_OID_OFFSET SPC_STATEMENT_TYPE_STRUCT, WVTAsn1SpcStatementTypeEncode,
  322. ASN1_OID_PREFIX SPC_STATEMENT_TYPE_OBJID, WVTAsn1SpcStatementTypeEncode,
  323. ASN1_OID_PREFIX CAT_NAMEVALUE_OBJID, WVTAsn1CatNameValueEncode,
  324. ASN1_OID_OFFSET CAT_NAMEVALUE_STRUCT, WVTAsn1CatNameValueEncode,
  325. ASN1_OID_PREFIX CAT_MEMBERINFO_OBJID, WVTAsn1CatMemberInfoEncode,
  326. ASN1_OID_OFFSET CAT_MEMBERINFO_STRUCT, WVTAsn1CatMemberInfoEncode,
  327. ASN1_OID_OFFSET SPC_SP_OPUS_INFO_STRUCT, WVTAsn1SpcSpOpusInfoEncode,
  328. ASN1_OID_PREFIX SPC_SP_OPUS_INFO_OBJID, WVTAsn1SpcSpOpusInfoEncode
  329. };
  330. #define SPC_ENCODE_FUNC_COUNT (sizeof(SpcEncodeFuncTable) / \
  331. sizeof(SpcEncodeFuncTable[0]))
  332. static const CRYPT_OID_FUNC_ENTRY SpcDecodeFuncTable[] =
  333. {
  334. ASN1_OID_OFFSET SPC_PE_IMAGE_DATA_STRUCT, WVTAsn1SpcPeImageDataDecode,
  335. ASN1_OID_PREFIX SPC_PE_IMAGE_DATA_OBJID, WVTAsn1SpcPeImageDataDecode,
  336. ASN1_OID_OFFSET SPC_CAB_DATA_STRUCT, WVTAsn1SpcLinkDecode,
  337. ASN1_OID_PREFIX SPC_CAB_DATA_OBJID, WVTAsn1SpcLinkDecode,
  338. ASN1_OID_OFFSET SPC_LINK_STRUCT, WVTAsn1SpcLinkDecode,
  339. ASN1_OID_PREFIX SPC_LINK_OBJID, WVTAsn1SpcLinkDecode,
  340. ASN1_OID_OFFSET SPC_SIGINFO_STRUCT, WVTAsn1SpcSigInfoDecode,
  341. ASN1_OID_PREFIX SPC_SIGINFO_OBJID, WVTAsn1SpcSigInfoDecode,
  342. ASN1_OID_OFFSET PKCS_UTC_TIME, WVTAsn1UtcTimeDecode,
  343. ASN1_OID_PREFIX szOID_RSA_signingTime, WVTAsn1UtcTimeDecode,
  344. ASN1_OID_OFFSET SPC_SP_AGENCY_INFO_STRUCT, WVTAsn1SpcSpAgencyInfoDecode,
  345. ASN1_OID_PREFIX SPC_SP_AGENCY_INFO_OBJID, WVTAsn1SpcSpAgencyInfoDecode,
  346. ASN1_OID_OFFSET SPC_SP_OPUS_INFO_STRUCT, WVTAsn1SpcSpOpusInfoDecode,
  347. ASN1_OID_PREFIX SPC_SP_OPUS_INFO_OBJID, WVTAsn1SpcSpOpusInfoDecode,
  348. ASN1_OID_OFFSET SPC_INDIRECT_DATA_CONTENT_STRUCT, WVTAsn1SpcIndirectDataContentDecode,
  349. ASN1_OID_PREFIX SPC_INDIRECT_DATA_OBJID, WVTAsn1SpcIndirectDataContentDecode,
  350. ASN1_OID_OFFSET SPC_SP_AGENCY_INFO_STRUCT, WVTAsn1SpcSpAgencyInfoDecode,
  351. ASN1_OID_PREFIX SPC_SP_AGENCY_INFO_OBJID, WVTAsn1SpcSpAgencyInfoDecode,
  352. ASN1_OID_OFFSET SPC_MINIMAL_CRITERIA_STRUCT, WVTAsn1SpcMinimalCriteriaInfoDecode,
  353. ASN1_OID_PREFIX SPC_MINIMAL_CRITERIA_OBJID, WVTAsn1SpcMinimalCriteriaInfoDecode,
  354. ASN1_OID_OFFSET SPC_FINANCIAL_CRITERIA_STRUCT, WVTAsn1SpcFinancialCriteriaInfoDecode,
  355. ASN1_OID_PREFIX SPC_FINANCIAL_CRITERIA_OBJID, WVTAsn1SpcFinancialCriteriaInfoDecode,
  356. ASN1_OID_OFFSET SPC_STATEMENT_TYPE_STRUCT, WVTAsn1SpcStatementTypeDecode,
  357. ASN1_OID_PREFIX SPC_STATEMENT_TYPE_OBJID, WVTAsn1SpcStatementTypeDecode,
  358. ASN1_OID_OFFSET CAT_NAMEVALUE_STRUCT, WVTAsn1CatNameValueDecode,
  359. ASN1_OID_PREFIX CAT_NAMEVALUE_OBJID, WVTAsn1CatNameValueDecode,
  360. ASN1_OID_OFFSET CAT_MEMBERINFO_STRUCT, WVTAsn1CatMemberInfoDecode,
  361. ASN1_OID_PREFIX CAT_MEMBERINFO_OBJID, WVTAsn1CatMemberInfoDecode,
  362. ASN1_OID_OFFSET SPC_FINANCIAL_CRITERIA_STRUCT, WVTAsn1SpcFinancialCriteriaInfoDecode,
  363. ASN1_OID_PREFIX SPC_FINANCIAL_CRITERIA_OBJID, WVTAsn1SpcFinancialCriteriaInfoDecode
  364. };
  365. #define SPC_DECODE_FUNC_COUNT (sizeof(SpcDecodeFuncTable) / \
  366. sizeof(SpcDecodeFuncTable[0]))
  367. //+-------------------------------------------------------------------------
  368. // Dll initialization
  369. //--------------------------------------------------------------------------
  370. HRESULT WINAPI ASNRegisterServer(LPCWSTR dllName)
  371. {
  372. int i;
  373. for (i = 0; i < SPC_REG_ENCODE_COUNT; i++)
  374. {
  375. if (!(CryptRegisterOIDFunction(X509_ASN_ENCODING, CRYPT_OID_ENCODE_OBJECT_FUNC,
  376. SpcRegEncodeTable[i].pszOID, dllName,
  377. SpcRegEncodeTable[i].pszOverrideFuncName)))
  378. {
  379. return(HError());
  380. }
  381. }
  382. for (i = 0; i < SPC_REG_DECODE_COUNT; i++)
  383. {
  384. if (!(CryptRegisterOIDFunction(X509_ASN_ENCODING, CRYPT_OID_DECODE_OBJECT_FUNC,
  385. SpcRegDecodeTable[i].pszOID, dllName,
  386. SpcRegDecodeTable[i].pszOverrideFuncName)))
  387. {
  388. return(HError());
  389. }
  390. }
  391. return S_OK;
  392. }
  393. HRESULT WINAPI ASNUnregisterServer()
  394. {
  395. HRESULT hr = S_OK;
  396. int i;
  397. for (i = 0; i < SPC_REG_ENCODE_COUNT; i++)
  398. {
  399. if (!(CryptUnregisterOIDFunction(X509_ASN_ENCODING, CRYPT_OID_ENCODE_OBJECT_FUNC,
  400. SpcRegEncodeTable[i].pszOID)))
  401. {
  402. if (ERROR_FILE_NOT_FOUND != GetLastError())
  403. {
  404. hr = HError();
  405. }
  406. }
  407. }
  408. for (i = 0; i < SPC_REG_DECODE_COUNT; i++)
  409. {
  410. if (!(CryptUnregisterOIDFunction(X509_ASN_ENCODING, CRYPT_OID_DECODE_OBJECT_FUNC,
  411. SpcRegDecodeTable[i].pszOID)))
  412. {
  413. if (ERROR_FILE_NOT_FOUND != GetLastError())
  414. {
  415. hr = HError();
  416. }
  417. }
  418. }
  419. return(hr);
  420. }
  421. BOOL WINAPI ASNDllMain(HMODULE hInst, ULONG ulReason, LPVOID lpReserved)
  422. {
  423. BOOL fRet;
  424. switch (ulReason)
  425. {
  426. case DLL_PROCESS_ATTACH:
  427. WTASN_Module_Startup();
  428. if (0 == (hAsn1Module = I_CryptInstallAsn1Module(
  429. WTASN_Module, 0, NULL)))
  430. {
  431. goto CryptInstallAsn1ModuleError;
  432. }
  433. /*
  434. if (!(CryptInstallOIDFunctionAddress(
  435. hInst,
  436. X509_ASN_ENCODING,
  437. CRYPT_OID_ENCODE_OBJECT_FUNC,
  438. SPC_ENCODE_FUNC_COUNT,
  439. SpcEncodeFuncTable,
  440. 0)))
  441. {
  442. goto CryptInstallOIDFunctionAddressError;
  443. }
  444. if (!(CryptInstallOIDFunctionAddress(
  445. hInst,
  446. X509_ASN_ENCODING,
  447. CRYPT_OID_DECODE_OBJECT_FUNC,
  448. SPC_DECODE_FUNC_COUNT,
  449. SpcDecodeFuncTable,
  450. CRYPT_INSTALL_OID_FUNC_BEFORE_FLAG)))
  451. {
  452. goto CryptInstallOIDFunctionAddressError;
  453. }
  454. */
  455. break;
  456. case DLL_PROCESS_DETACH:
  457. I_CryptUninstallAsn1Module(hAsn1Module);
  458. WTASN_Module_Cleanup();
  459. break;
  460. case DLL_THREAD_DETACH:
  461. default:
  462. break;
  463. }
  464. fRet = TRUE;
  465. CommonReturn:
  466. return(fRet);
  467. ErrorReturn:
  468. fRet = FALSE;
  469. goto CommonReturn;
  470. TRACE_ERROR_EX(DBG_SS,CryptInstallAsn1ModuleError)
  471. //TRACE_ERROR_EX(DBG_SS,CryptInstallOIDFunctionAddressError)
  472. }
  473. //+-------------------------------------------------------------------------
  474. // Set/Get "Any" DER BLOB
  475. //--------------------------------------------------------------------------
  476. inline void WVTAsn1SetAny(IN PCRYPT_OBJID_BLOB pInfo, OUT NOCOPYANY *pOss)
  477. {
  478. PkiAsn1SetAny(pInfo, pOss);
  479. }
  480. inline void WVTAsn1GetAny(IN NOCOPYANY *pOss, IN DWORD dwFlags, OUT PCRYPT_OBJID_BLOB pInfo,
  481. IN OUT BYTE **ppbExtra, IN OUT LONG *plRemainExtra)
  482. {
  483. PkiAsn1GetAny(pOss, dwFlags, pInfo, ppbExtra, plRemainExtra);
  484. }
  485. //+-------------------------------------------------------------------------
  486. // Set/Get CRYPT_DATA_BLOB (Octet String)
  487. //--------------------------------------------------------------------------
  488. inline void WVTAsn1SetOctetString(IN PCRYPT_DATA_BLOB pInfo, OUT OCTETSTRING *pOss)
  489. {
  490. pOss->value = pInfo->pbData;
  491. pOss->length = pInfo->cbData;
  492. }
  493. inline void WVTAsn1GetOctetString(
  494. IN OCTETSTRING *pOss,
  495. IN DWORD dwFlags,
  496. OUT PCRYPT_DATA_BLOB pInfo,
  497. IN OUT BYTE **ppbExtra,
  498. IN OUT LONG *plRemainExtra
  499. )
  500. {
  501. PkiAsn1GetOctetString(pOss->length, pOss->value, dwFlags,
  502. pInfo, ppbExtra, plRemainExtra);
  503. }
  504. inline void WVTAsn1SetBit(IN PCRYPT_BIT_BLOB pInfo, OUT BITSTRING *pOss)
  505. {
  506. PkiAsn1SetBitString(pInfo, &pOss->length, &pOss->value);
  507. }
  508. inline void WVTAsn1GetBit(IN BITSTRING *pOss, IN DWORD dwFlags,
  509. OUT PCRYPT_BIT_BLOB pInfo,
  510. IN OUT BYTE **ppbExtra,
  511. IN OUT LONG *plRemainExtra)
  512. {
  513. PkiAsn1GetBitString(pOss->length, pOss->value, dwFlags,
  514. pInfo, ppbExtra, plRemainExtra);
  515. }
  516. //+-------------------------------------------------------------------------
  517. // Set/Free/Get Unicode mapped to IA5 String
  518. //--------------------------------------------------------------------------
  519. inline BOOL WVTAsn1SetUnicodeConvertedToIA5(
  520. IN LPWSTR pwsz,
  521. OUT IA5STRING *pOss
  522. )
  523. {
  524. return PkiAsn1SetUnicodeConvertedToIA5String(pwsz,
  525. &pOss->length, &pOss->value);
  526. }
  527. inline void WVTAsn1FreeUnicodeConvertedToIA5(IN IA5STRING *pOss)
  528. {
  529. PkiAsn1FreeUnicodeConvertedToIA5String(pOss->value);
  530. pOss->value = NULL;
  531. }
  532. inline void WVTAsn1GetIA5ConvertedToUnicode(
  533. IN IA5STRING *pOss,
  534. IN DWORD dwFlags,
  535. OUT LPWSTR *ppwsz,
  536. IN OUT BYTE **ppbExtra,
  537. IN OUT LONG *plRemainExtra
  538. )
  539. {
  540. PkiAsn1GetIA5StringConvertedToUnicode(pOss->length, pOss->value, dwFlags,
  541. ppwsz, ppbExtra, plRemainExtra);
  542. }
  543. //+-------------------------------------------------------------------------
  544. // Set/Get LPWSTR (BMP String)
  545. //--------------------------------------------------------------------------
  546. inline void WVTAsn1SetBMP(
  547. IN LPWSTR pwsz,
  548. OUT BMPSTRING *pOss
  549. )
  550. {
  551. pOss->value = pwsz;
  552. pOss->length = wcslen(pwsz);
  553. }
  554. inline void WVTAsn1GetBMP(
  555. IN BMPSTRING *pOss,
  556. IN DWORD dwFlags,
  557. OUT LPWSTR *ppwsz,
  558. IN OUT BYTE **ppbExtra,
  559. IN OUT LONG *plRemainExtra
  560. )
  561. {
  562. PkiAsn1GetBMPString(pOss->length, pOss->value, dwFlags,
  563. ppwsz, ppbExtra, plRemainExtra);
  564. }
  565. //+-------------------------------------------------------------------------
  566. // Set/Get Spc String
  567. //--------------------------------------------------------------------------
  568. void WVTAsn1SetSpcString(
  569. IN LPWSTR pwsz,
  570. OUT SpcString *pOss
  571. )
  572. {
  573. pOss->choice = unicode_chosen;
  574. WVTAsn1SetBMP(pwsz, &pOss->u.unicode);
  575. }
  576. void WVTAsn1GetSpcString(
  577. IN SpcString *pOss,
  578. IN DWORD dwFlags,
  579. OUT LPWSTR *ppwsz,
  580. IN OUT BYTE **ppbExtra,
  581. IN OUT LONG *plRemainExtra
  582. )
  583. {
  584. switch (pOss->choice) {
  585. case unicode_chosen:
  586. WVTAsn1GetBMP(&pOss->u.unicode, dwFlags,
  587. ppwsz, ppbExtra, plRemainExtra);
  588. break;
  589. case ascii_chosen:
  590. WVTAsn1GetIA5ConvertedToUnicode(&pOss->u.ascii, dwFlags,
  591. ppwsz, ppbExtra, plRemainExtra);
  592. break;
  593. default:
  594. if (*plRemainExtra >= 0)
  595. *ppwsz = NULL;
  596. }
  597. }
  598. //+-------------------------------------------------------------------------
  599. // Set/Get Spc Link
  600. //--------------------------------------------------------------------------
  601. BOOL WVTAsn1SetSpcLink(
  602. IN PSPC_LINK pInfo,
  603. OUT SpcLink *pOss
  604. )
  605. {
  606. BOOL fRet = TRUE;
  607. memset(pOss, 0, sizeof(*pOss));
  608. // Assumption: OSS choice == dwLinkChoice
  609. // WVTAsn1GetSpcLink has asserts to verify
  610. pOss->choice = (unsigned short) pInfo->dwLinkChoice;
  611. switch (pInfo->dwLinkChoice) {
  612. case SPC_URL_LINK_CHOICE:
  613. fRet = WVTAsn1SetUnicodeConvertedToIA5(pInfo->pwszUrl, &pOss->u.url);
  614. break;
  615. case SPC_MONIKER_LINK_CHOICE:
  616. pOss->u.moniker.classId.length = sizeof(pInfo->Moniker.ClassId);
  617. pOss->u.moniker.classId.value = pInfo->Moniker.ClassId;
  618. WVTAsn1SetOctetString(&pInfo->Moniker.SerializedData,
  619. &pOss->u.moniker.serializedData);
  620. break;
  621. case SPC_FILE_LINK_CHOICE:
  622. WVTAsn1SetSpcString(pInfo->pwszFile, &pOss->u.file);
  623. break;
  624. default:
  625. SetLastError((DWORD) E_INVALIDARG);
  626. fRet = FALSE;
  627. }
  628. return fRet;
  629. }
  630. void WVTAsn1FreeSpcLink(
  631. IN SpcLink *pOss
  632. )
  633. {
  634. if (pOss->choice == url_chosen)
  635. WVTAsn1FreeUnicodeConvertedToIA5(&pOss->u.url);
  636. }
  637. BOOL WVTAsn1GetSpcLink(
  638. IN SpcLink *pOss,
  639. IN DWORD dwFlags,
  640. OUT PSPC_LINK pInfo,
  641. IN OUT BYTE **ppbExtra,
  642. IN OUT LONG *plRemainExtra
  643. )
  644. {
  645. DWORD dwLinkChoice;
  646. assert(url_chosen == SPC_URL_LINK_CHOICE);
  647. assert(moniker_chosen == SPC_MONIKER_LINK_CHOICE);
  648. assert(file_chosen == SPC_FILE_LINK_CHOICE);
  649. dwLinkChoice = pOss->choice;
  650. if (*plRemainExtra >= 0) {
  651. memset(pInfo, 0, sizeof(*pInfo));
  652. pInfo->dwLinkChoice = dwLinkChoice;
  653. }
  654. switch (dwLinkChoice) {
  655. case SPC_URL_LINK_CHOICE:
  656. WVTAsn1GetIA5ConvertedToUnicode(&pOss->u.url, dwFlags,
  657. &pInfo->pwszUrl, ppbExtra, plRemainExtra);
  658. break;
  659. case SPC_MONIKER_LINK_CHOICE:
  660. if (sizeof(pInfo->Moniker.ClassId) != pOss->u.moniker.classId.length) {
  661. SetLastError((DWORD) CRYPT_E_BAD_ENCODE);
  662. return FALSE;
  663. }
  664. if (*plRemainExtra >= 0) {
  665. memcpy(pInfo->Moniker.ClassId, pOss->u.moniker.classId.value,
  666. sizeof(pInfo->Moniker.ClassId));
  667. }
  668. WVTAsn1GetOctetString(&pOss->u.moniker.serializedData, dwFlags,
  669. &pInfo->Moniker.SerializedData, ppbExtra, plRemainExtra);
  670. break;
  671. case SPC_FILE_LINK_CHOICE:
  672. WVTAsn1GetSpcString(&pOss->u.file, dwFlags,
  673. &pInfo->pwszFile, ppbExtra, plRemainExtra);
  674. break;
  675. default:
  676. SetLastError((DWORD) CRYPT_E_BAD_ENCODE);
  677. return FALSE;
  678. }
  679. return TRUE;
  680. }
  681. BOOL WVTAsn1GetSpcLinkPointer(
  682. IN SpcLink *pOss,
  683. IN DWORD dwFlags,
  684. OUT PSPC_LINK *pInfo,
  685. IN OUT BYTE **ppbExtra,
  686. IN OUT LONG *plRemainExtra
  687. )
  688. {
  689. LONG lAlignExtra;
  690. PSPC_LINK pLink;
  691. lAlignExtra = INFO_LEN_ALIGN(sizeof(SPC_LINK));
  692. *plRemainExtra -= lAlignExtra;
  693. if (*plRemainExtra >= 0) {
  694. pLink = (PSPC_LINK) *ppbExtra;
  695. *pInfo = pLink;
  696. *ppbExtra += lAlignExtra;
  697. } else
  698. pLink = NULL;
  699. return WVTAsn1GetSpcLink(
  700. pOss,
  701. dwFlags,
  702. pLink,
  703. ppbExtra,
  704. plRemainExtra
  705. );
  706. }
  707. BOOL WVTAsn1SetSpcSigInfo(IN PSPC_SIGINFO pInfo, OUT SpcSigInfo *pOss)
  708. {
  709. memset(pOss, 0x00, sizeof(*pOss));
  710. pOss->dwSIPversion = pInfo->dwSipVersion;
  711. pOss->gSIPguid.length = sizeof(GUID);
  712. pOss->gSIPguid.value = (BYTE *) &pInfo->gSIPGuid;
  713. pOss->dwReserved1 = pInfo->dwReserved1;
  714. pOss->dwReserved2 = pInfo->dwReserved2;
  715. pOss->dwReserved3 = pInfo->dwReserved3;
  716. pOss->dwReserved4 = pInfo->dwReserved4;
  717. pOss->dwReserved5 = pInfo->dwReserved5;
  718. return(TRUE);
  719. }
  720. BOOL WVTAsn1GetSpcSigInfo(IN SpcSigInfo *pOss, IN DWORD dwFlags,
  721. OUT PSPC_SIGINFO pInfo, IN OUT BYTE **ppbExtra,
  722. IN OUT LONG *plRemainExtra)
  723. {
  724. if (!(pInfo))
  725. {
  726. return(TRUE);
  727. }
  728. pInfo->dwSipVersion = pOss->dwSIPversion;
  729. if (sizeof(GUID) != pOss->gSIPguid.length) {
  730. SetLastError((DWORD) CRYPT_E_BAD_ENCODE);
  731. return FALSE;
  732. }
  733. memcpy(&pInfo->gSIPGuid, pOss->gSIPguid.value, sizeof(GUID));
  734. pInfo->dwReserved1 = pOss->dwReserved1;
  735. pInfo->dwReserved2 = pOss->dwReserved2;
  736. pInfo->dwReserved3 = pOss->dwReserved3;
  737. pInfo->dwReserved4 = pOss->dwReserved4;
  738. pInfo->dwReserved5 = pOss->dwReserved5;
  739. return(TRUE);
  740. }
  741. //+-------------------------------------------------------------------------
  742. // Set/Get Object Identifier string
  743. //--------------------------------------------------------------------------
  744. BOOL WVTAsn1SetObjId(
  745. IN LPSTR pszObjId,
  746. OUT ObjectID *pOss
  747. )
  748. {
  749. pOss->count = sizeof(pOss->value) / sizeof(pOss->value[0]);
  750. if (PkiAsn1ToObjectIdentifier(pszObjId, &pOss->count, pOss->value))
  751. return TRUE;
  752. else {
  753. SetLastError((DWORD) CRYPT_E_BAD_ENCODE);
  754. return FALSE;
  755. }
  756. }
  757. void WVTAsn1GetObjId(
  758. IN ObjectID *pOss,
  759. IN DWORD dwFlags,
  760. OUT LPSTR *ppszObjId,
  761. IN OUT BYTE **ppbExtra,
  762. IN OUT LONG *plRemainExtra
  763. )
  764. {
  765. LONG lRemainExtra = *plRemainExtra;
  766. BYTE *pbExtra = *ppbExtra;
  767. LONG lAlignExtra;
  768. DWORD cbObjId;
  769. cbObjId = lRemainExtra > 0 ? lRemainExtra : 0;
  770. PkiAsn1FromObjectIdentifier(
  771. pOss->count,
  772. pOss->value,
  773. (LPSTR) pbExtra,
  774. &cbObjId
  775. );
  776. lAlignExtra = INFO_LEN_ALIGN(cbObjId);
  777. lRemainExtra -= lAlignExtra;
  778. if (lRemainExtra >= 0) {
  779. if(cbObjId) {
  780. *ppszObjId = (LPSTR) pbExtra;
  781. } else
  782. *ppszObjId = NULL;
  783. pbExtra += lAlignExtra;
  784. }
  785. *plRemainExtra = lRemainExtra;
  786. *ppbExtra = pbExtra;
  787. }
  788. //+-------------------------------------------------------------------------
  789. // Set/Get CRYPT_ALGORITHM_IDENTIFIER
  790. //--------------------------------------------------------------------------
  791. BOOL WVTAsn1SetAlgorithm(
  792. IN PCRYPT_ALGORITHM_IDENTIFIER pInfo,
  793. OUT AlgorithmIdentifier *pOss
  794. )
  795. {
  796. memset(pOss, 0, sizeof(*pOss));
  797. if (pInfo->pszObjId) {
  798. if (!WVTAsn1SetObjId(pInfo->pszObjId, &pOss->algorithm))
  799. return FALSE;
  800. if (pInfo->Parameters.cbData)
  801. WVTAsn1SetAny(&pInfo->Parameters, &pOss->parameters);
  802. else
  803. // Per PKCS #1: default to the ASN.1 type NULL.
  804. WVTAsn1SetAny((PCRYPT_OBJID_BLOB) &NullDerBlob, &pOss->parameters);
  805. pOss->bit_mask |= parameters_present;
  806. }
  807. return TRUE;
  808. }
  809. void WVTAsn1GetAlgorithm(
  810. IN AlgorithmIdentifier *pOss,
  811. IN DWORD dwFlags,
  812. OUT PCRYPT_ALGORITHM_IDENTIFIER pInfo,
  813. IN OUT BYTE **ppbExtra,
  814. IN OUT LONG *plRemainExtra
  815. )
  816. {
  817. if (*plRemainExtra >= 0)
  818. memset(pInfo, 0, sizeof(*pInfo));
  819. WVTAsn1GetObjId(&pOss->algorithm, dwFlags, &pInfo->pszObjId,
  820. ppbExtra, plRemainExtra);
  821. if (pOss->bit_mask & parameters_present)
  822. WVTAsn1GetAny(&pOss->parameters, dwFlags, &pInfo->Parameters,
  823. ppbExtra, plRemainExtra);
  824. }
  825. //+-------------------------------------------------------------------------
  826. // Encode an OSS formatted info structure
  827. //
  828. // Called by the WVTAsn1*Encode() functions.
  829. //--------------------------------------------------------------------------
  830. BOOL WVTAsn1InfoEncode(
  831. IN int pdunum,
  832. IN void *pOssInfo,
  833. OUT BYTE *pbEncoded,
  834. IN OUT DWORD *pcbEncoded
  835. )
  836. {
  837. return PkiAsn1EncodeInfo(
  838. GetEncoder(),
  839. pdunum,
  840. pOssInfo,
  841. pbEncoded,
  842. pcbEncoded);
  843. }
  844. //+-------------------------------------------------------------------------
  845. // Decode into an allocated, OSS formatted info structure
  846. //
  847. // Called by the WVTAsn1*Decode() functions.
  848. //--------------------------------------------------------------------------
  849. BOOL WVTAsn1InfoDecodeAndAlloc(
  850. IN int pdunum,
  851. IN const BYTE *pbEncoded,
  852. IN DWORD cbEncoded,
  853. OUT void **ppOssInfo
  854. )
  855. {
  856. return PkiAsn1DecodeAndAllocInfo(
  857. GetDecoder(),
  858. pdunum,
  859. pbEncoded,
  860. cbEncoded,
  861. ppOssInfo);
  862. }
  863. //+-------------------------------------------------------------------------
  864. // Free an allocated, OSS formatted info structure
  865. //
  866. // Called by the WVTAsn1*Decode() functions.
  867. //--------------------------------------------------------------------------
  868. void WVTAsn1InfoFree(
  869. IN int pdunum,
  870. IN void *pOssInfo
  871. )
  872. {
  873. if (pOssInfo) {
  874. DWORD dwErr = GetLastError();
  875. // TlsGetValue globbers LastError
  876. PkiAsn1FreeInfo(GetDecoder(), pdunum, pOssInfo);
  877. SetLastError(dwErr);
  878. }
  879. }
  880. //+-------------------------------------------------------------------------
  881. // SPC PKCS #7 Indirect Data Content Encode (OSS X509)
  882. //--------------------------------------------------------------------------
  883. BOOL WINAPI WVTAsn1SpcIndirectDataContentEncode(
  884. IN DWORD dwCertEncodingType,
  885. IN LPCSTR lpszStructType,
  886. IN PSPC_INDIRECT_DATA_CONTENT pInfo,
  887. OUT BYTE *pbEncoded,
  888. IN OUT DWORD *pcbEncoded
  889. )
  890. {
  891. BOOL fResult;
  892. SpcIndirectDataContent OssInfo;
  893. memset(&OssInfo, 0, sizeof(OssInfo));
  894. if (!WVTAsn1SetObjId(pInfo->Data.pszObjId, &OssInfo.data.type))
  895. goto ErrorReturn;
  896. if (pInfo->Data.Value.cbData) {
  897. WVTAsn1SetAny(&pInfo->Data.Value, &OssInfo.data.value);
  898. OssInfo.data.bit_mask |= value_present;
  899. }
  900. if (!WVTAsn1SetAlgorithm(&pInfo->DigestAlgorithm,
  901. &OssInfo.messageDigest.digestAlgorithm))
  902. goto ErrorReturn;
  903. WVTAsn1SetOctetString(&pInfo->Digest, &OssInfo.messageDigest.digest);
  904. fResult = WVTAsn1InfoEncode(
  905. SpcIndirectDataContent_PDU,
  906. &OssInfo,
  907. pbEncoded,
  908. pcbEncoded
  909. );
  910. goto CommonReturn;
  911. ErrorReturn:
  912. *pcbEncoded = 0;
  913. fResult = FALSE;
  914. CommonReturn:
  915. return fResult;
  916. }
  917. //+-------------------------------------------------------------------------
  918. // SPC PKCS #7 Indirect Data Content Decode (OSS X509)
  919. //--------------------------------------------------------------------------
  920. BOOL WINAPI WVTAsn1SpcIndirectDataContentDecode(
  921. IN DWORD dwCertEncodingType,
  922. IN LPCSTR lpszStructType,
  923. IN const BYTE *pbEncoded,
  924. IN DWORD cbEncoded,
  925. IN DWORD dwFlags,
  926. OUT PSPC_INDIRECT_DATA_CONTENT pInfo,
  927. IN OUT DWORD *pcbInfo
  928. )
  929. {
  930. BOOL fResult;
  931. SpcIndirectDataContent *pOssInfo = NULL;
  932. BYTE *pbExtra;
  933. LONG lRemainExtra;
  934. if (pInfo == NULL)
  935. *pcbInfo = 0;
  936. if (!WVTAsn1InfoDecodeAndAlloc(
  937. SpcIndirectDataContent_PDU,
  938. pbEncoded,
  939. cbEncoded,
  940. (void **) &pOssInfo))
  941. goto ErrorReturn;
  942. // for lRemainExtra < 0, LENGTH_ONLY calculation
  943. lRemainExtra = (LONG) *pcbInfo - sizeof(SPC_INDIRECT_DATA_CONTENT);
  944. if (lRemainExtra < 0) {
  945. pbExtra = NULL;
  946. } else {
  947. // Default all optional fields to zero
  948. memset(pInfo, 0, sizeof(SPC_INDIRECT_DATA_CONTENT));
  949. pbExtra = (BYTE *) pInfo + sizeof(SPC_INDIRECT_DATA_CONTENT);
  950. }
  951. WVTAsn1GetObjId(&pOssInfo->data.type, dwFlags, &pInfo->Data.pszObjId,
  952. &pbExtra, &lRemainExtra);
  953. if (pOssInfo->data.bit_mask & value_present)
  954. WVTAsn1GetAny(&pOssInfo->data.value, dwFlags, &pInfo->Data.Value,
  955. &pbExtra, &lRemainExtra);
  956. WVTAsn1GetAlgorithm(&pOssInfo->messageDigest.digestAlgorithm, dwFlags,
  957. &pInfo->DigestAlgorithm, &pbExtra, &lRemainExtra);
  958. WVTAsn1GetOctetString(&pOssInfo->messageDigest.digest, dwFlags,
  959. &pInfo->Digest, &pbExtra, &lRemainExtra);
  960. if (lRemainExtra >= 0)
  961. *pcbInfo = *pcbInfo - (DWORD) lRemainExtra;
  962. else {
  963. *pcbInfo = *pcbInfo + (DWORD) -lRemainExtra;
  964. if (pInfo) goto LengthError;
  965. }
  966. fResult = TRUE;
  967. goto CommonReturn;
  968. LengthError:
  969. SetLastError((DWORD) ERROR_MORE_DATA);
  970. fResult = FALSE;
  971. goto CommonReturn;
  972. ErrorReturn:
  973. *pcbInfo = 0;
  974. fResult = FALSE;
  975. CommonReturn:
  976. WVTAsn1InfoFree(SpcIndirectDataContent_PDU, pOssInfo);
  977. return fResult;
  978. }
  979. BOOL WINAPI WVTAsn1UtcTimeDecode(
  980. IN DWORD dwCertEncodingType,
  981. IN LPCSTR lpszStructType,
  982. IN const BYTE *pbEncoded,
  983. IN DWORD cbEncoded,
  984. IN DWORD dwFlags,
  985. OUT FILETIME * pFileTime,
  986. IN OUT DWORD *pcbFileTime
  987. ) {
  988. BOOL fResult;
  989. UtcTime * putcTime = NULL;
  990. assert(pcbFileTime != NULL);
  991. if(pFileTime == NULL) {
  992. *pcbFileTime = sizeof(FILETIME);
  993. return(TRUE);
  994. }
  995. if (*pcbFileTime < sizeof(FILETIME)) {
  996. *pcbFileTime = sizeof(FILETIME);
  997. SetLastError((DWORD) ERROR_MORE_DATA);
  998. return(FALSE);
  999. }
  1000. *pcbFileTime = sizeof(FILETIME);
  1001. if (!WVTAsn1InfoDecodeAndAlloc(
  1002. UtcTime_PDU,
  1003. pbEncoded,
  1004. cbEncoded,
  1005. (void **) &putcTime))
  1006. goto WVTAsn1InfoDecodeAndAllocError;
  1007. if( !PkiAsn1FromUTCTime(putcTime, pFileTime) )
  1008. goto PkiAsn1FromUTCTimeError;
  1009. fResult = TRUE;
  1010. CommonReturn:
  1011. WVTAsn1InfoFree(UtcTime_PDU, putcTime);
  1012. return fResult;
  1013. ErrorReturn:
  1014. *pcbFileTime = 0;
  1015. fResult = FALSE;
  1016. goto CommonReturn;
  1017. TRACE_ERROR_EX(DBG_SS,WVTAsn1InfoDecodeAndAllocError);
  1018. TRACE_ERROR_EX(DBG_SS,PkiAsn1FromUTCTimeError);
  1019. }
  1020. //+-------------------------------------------------------------------------
  1021. // SPC SP Agency Info Encode (OSS X509)
  1022. //--------------------------------------------------------------------------
  1023. BOOL WINAPI WVTAsn1SpcSpAgencyInfoEncode(
  1024. IN DWORD dwCertEncodingType,
  1025. IN LPCSTR lpszStructType,
  1026. IN PSPC_SP_AGENCY_INFO pInfo,
  1027. OUT BYTE *pbEncoded,
  1028. IN OUT DWORD *pcbEncoded
  1029. )
  1030. {
  1031. BOOL fResult;
  1032. SpcSpAgencyInformation OssInfo;
  1033. memset(&OssInfo, 0, sizeof(OssInfo));
  1034. if (pInfo->pPolicyInformation) {
  1035. if (!WVTAsn1SetSpcLink(pInfo->pPolicyInformation,
  1036. &OssInfo.policyInformation))
  1037. goto ErrorReturn;
  1038. OssInfo.bit_mask |= policyInformation_present;
  1039. }
  1040. if (pInfo->pwszPolicyDisplayText) {
  1041. WVTAsn1SetSpcString(pInfo->pwszPolicyDisplayText,
  1042. &OssInfo.policyDisplayText);
  1043. OssInfo.bit_mask |= policyDisplayText_present;
  1044. }
  1045. if (pInfo->pLogoImage) {
  1046. PSPC_IMAGE pImage = pInfo->pLogoImage;
  1047. if (pImage->pImageLink) {
  1048. if (!WVTAsn1SetSpcLink(pImage->pImageLink,
  1049. &OssInfo.logoImage.imageLink))
  1050. goto ErrorReturn;
  1051. OssInfo.logoImage.bit_mask |= imageLink_present;
  1052. }
  1053. if (pImage->Bitmap.cbData != 0) {
  1054. WVTAsn1SetOctetString(&pImage->Bitmap, &OssInfo.logoImage.bitmap);
  1055. OssInfo.logoImage.bit_mask |= bitmap_present;
  1056. }
  1057. if (pImage->Metafile.cbData != 0) {
  1058. WVTAsn1SetOctetString(&pImage->Metafile,
  1059. &OssInfo.logoImage.metafile);
  1060. OssInfo.logoImage.bit_mask |= metafile_present;
  1061. }
  1062. if (pImage->EnhancedMetafile.cbData != 0) {
  1063. WVTAsn1SetOctetString(&pImage->EnhancedMetafile,
  1064. &OssInfo.logoImage.enhancedMetafile);
  1065. OssInfo.logoImage.bit_mask |= enhancedMetafile_present;
  1066. }
  1067. if (pImage->GifFile.cbData != 0) {
  1068. WVTAsn1SetOctetString(&pImage->GifFile,
  1069. &OssInfo.logoImage.gifFile);
  1070. OssInfo.logoImage.bit_mask |= gifFile_present;
  1071. }
  1072. OssInfo.bit_mask |= logoImage_present;
  1073. }
  1074. if (pInfo->pLogoLink) {
  1075. if (!WVTAsn1SetSpcLink(pInfo->pLogoLink, &OssInfo.logoLink))
  1076. goto ErrorReturn;
  1077. OssInfo.bit_mask |= logoLink_present;
  1078. }
  1079. fResult = WVTAsn1InfoEncode(
  1080. SpcSpAgencyInformation_PDU,
  1081. &OssInfo,
  1082. pbEncoded,
  1083. pcbEncoded
  1084. );
  1085. goto CommonReturn;
  1086. ErrorReturn:
  1087. *pcbEncoded = 0;
  1088. fResult = FALSE;
  1089. CommonReturn:
  1090. WVTAsn1FreeSpcLink(&OssInfo.policyInformation);
  1091. WVTAsn1FreeSpcLink(&OssInfo.logoImage.imageLink);
  1092. WVTAsn1FreeSpcLink(&OssInfo.logoLink);
  1093. return fResult;
  1094. }
  1095. //+-------------------------------------------------------------------------
  1096. // SPC SP Agency Info Decode (OSS X509)
  1097. //--------------------------------------------------------------------------
  1098. BOOL WINAPI WVTAsn1SpcSpAgencyInfoDecode(
  1099. IN DWORD dwCertEncodingType,
  1100. IN LPCSTR lpszStructType,
  1101. IN const BYTE *pbEncoded,
  1102. IN DWORD cbEncoded,
  1103. IN DWORD dwFlags,
  1104. OUT PSPC_SP_AGENCY_INFO pInfo,
  1105. IN OUT DWORD *pcbInfo
  1106. )
  1107. {
  1108. BOOL fResult;
  1109. SpcSpAgencyInformation *pOssInfo = NULL;
  1110. BYTE *pbExtra;
  1111. LONG lRemainExtra;
  1112. LONG lAlignExtra;
  1113. if (pInfo == NULL)
  1114. *pcbInfo = 0;
  1115. if (!WVTAsn1InfoDecodeAndAlloc(
  1116. SpcSpAgencyInformation_PDU,
  1117. pbEncoded,
  1118. cbEncoded,
  1119. (void **) &pOssInfo))
  1120. goto ErrorReturn;
  1121. // for lRemainExtra < 0, LENGTH_ONLY calculation
  1122. lRemainExtra = (LONG) *pcbInfo - sizeof(SPC_SP_AGENCY_INFO);
  1123. if (lRemainExtra < 0) {
  1124. pbExtra = NULL;
  1125. } else {
  1126. // Default all optional fields to zero
  1127. memset(pInfo, 0, sizeof(SPC_SP_AGENCY_INFO));
  1128. pbExtra = (BYTE *) pInfo + sizeof(SPC_SP_AGENCY_INFO);
  1129. }
  1130. if (pOssInfo->bit_mask & policyInformation_present) {
  1131. if (!WVTAsn1GetSpcLinkPointer(&pOssInfo->policyInformation, dwFlags,
  1132. &pInfo->pPolicyInformation, &pbExtra, &lRemainExtra))
  1133. goto ErrorReturn;
  1134. }
  1135. if (pOssInfo->bit_mask & policyDisplayText_present) {
  1136. WVTAsn1GetSpcString(&pOssInfo->policyDisplayText, dwFlags,
  1137. &pInfo->pwszPolicyDisplayText, &pbExtra, &lRemainExtra);
  1138. }
  1139. if (pOssInfo->bit_mask & logoImage_present) {
  1140. PSPC_IMAGE pImage;
  1141. SpcImage *pOssImage = &pOssInfo->logoImage;
  1142. lAlignExtra = INFO_LEN_ALIGN(sizeof(SPC_IMAGE));
  1143. lRemainExtra -= lAlignExtra;
  1144. if (lRemainExtra >= 0) {
  1145. pImage = (PSPC_IMAGE) pbExtra;
  1146. memset(pImage, 0, sizeof(SPC_IMAGE));
  1147. pInfo->pLogoImage = pImage;
  1148. pbExtra += lAlignExtra;
  1149. } else
  1150. pImage = NULL;
  1151. if (pOssImage->bit_mask & imageLink_present) {
  1152. if (!WVTAsn1GetSpcLinkPointer(&pOssImage->imageLink, dwFlags,
  1153. &pImage->pImageLink, &pbExtra, &lRemainExtra))
  1154. goto ErrorReturn;
  1155. }
  1156. if (pOssImage->bit_mask & bitmap_present) {
  1157. WVTAsn1GetOctetString(&pOssImage->bitmap, dwFlags,
  1158. &pImage->Bitmap, &pbExtra, &lRemainExtra);
  1159. }
  1160. if (pOssImage->bit_mask & metafile_present) {
  1161. WVTAsn1GetOctetString(&pOssImage->metafile, dwFlags,
  1162. &pImage->Metafile, &pbExtra, &lRemainExtra);
  1163. }
  1164. if (pOssImage->bit_mask & enhancedMetafile_present) {
  1165. WVTAsn1GetOctetString(&pOssImage->enhancedMetafile, dwFlags,
  1166. &pImage->EnhancedMetafile, &pbExtra, &lRemainExtra);
  1167. }
  1168. if (pOssImage->bit_mask & gifFile_present) {
  1169. WVTAsn1GetOctetString(&pOssImage->gifFile, dwFlags,
  1170. &pImage->GifFile, &pbExtra, &lRemainExtra);
  1171. }
  1172. }
  1173. if (pOssInfo->bit_mask & logoLink_present) {
  1174. if (!WVTAsn1GetSpcLinkPointer(&pOssInfo->logoLink, dwFlags,
  1175. &pInfo->pLogoLink, &pbExtra, &lRemainExtra))
  1176. goto ErrorReturn;
  1177. }
  1178. if (lRemainExtra >= 0)
  1179. *pcbInfo = *pcbInfo - (DWORD) lRemainExtra;
  1180. else {
  1181. *pcbInfo = *pcbInfo + (DWORD) -lRemainExtra;
  1182. if (pInfo) goto LengthError;
  1183. }
  1184. fResult = TRUE;
  1185. goto CommonReturn;
  1186. LengthError:
  1187. SetLastError((DWORD) ERROR_MORE_DATA);
  1188. fResult = FALSE;
  1189. goto CommonReturn;
  1190. ErrorReturn:
  1191. *pcbInfo = 0;
  1192. fResult = FALSE;
  1193. CommonReturn:
  1194. WVTAsn1InfoFree(SpcSpAgencyInformation_PDU, pOssInfo);
  1195. return fResult;
  1196. }
  1197. //+-------------------------------------------------------------------------
  1198. // SPC Minimal Criteria Info Encode (OSS X509)
  1199. //--------------------------------------------------------------------------
  1200. BOOL WINAPI WVTAsn1SpcMinimalCriteriaInfoEncode(
  1201. IN DWORD dwCertEncodingType,
  1202. IN LPCSTR lpszStructType,
  1203. IN BOOL *pInfo,
  1204. OUT BYTE *pbEncoded,
  1205. IN OUT DWORD *pcbEncoded
  1206. )
  1207. {
  1208. ossBoolean OssInfo = (ossBoolean) *pInfo;
  1209. return WVTAsn1InfoEncode(
  1210. SpcMinimalCriteria_PDU,
  1211. &OssInfo,
  1212. pbEncoded,
  1213. pcbEncoded
  1214. );
  1215. }
  1216. //+-------------------------------------------------------------------------
  1217. // SPC Minimal Criteria Info Encode (OSS X509)
  1218. //--------------------------------------------------------------------------
  1219. BOOL WINAPI WVTAsn1SpcMinimalCriteriaInfoDecode(
  1220. IN DWORD dwCertEncodingType,
  1221. IN LPCSTR lpszStructType,
  1222. IN const BYTE *pbEncoded,
  1223. IN DWORD cbEncoded,
  1224. IN DWORD dwFlags,
  1225. OUT BOOL *pInfo,
  1226. IN OUT DWORD *pcbInfo
  1227. )
  1228. {
  1229. BOOL fResult;
  1230. ossBoolean *pOssInfo = NULL;
  1231. if (pInfo == NULL)
  1232. *pcbInfo = 0;
  1233. if ((fResult = WVTAsn1InfoDecodeAndAlloc(
  1234. SpcMinimalCriteria_PDU,
  1235. pbEncoded,
  1236. cbEncoded,
  1237. (void **) &pOssInfo))) {
  1238. if (*pcbInfo < sizeof(BOOL)) {
  1239. if (pInfo) {
  1240. fResult = FALSE;
  1241. SetLastError((DWORD) ERROR_MORE_DATA);
  1242. }
  1243. } else
  1244. *pInfo = (BOOL) *pOssInfo;
  1245. *pcbInfo = sizeof(BOOL);
  1246. } else {
  1247. if (*pcbInfo >= sizeof(BOOL))
  1248. *pInfo = FALSE;
  1249. *pcbInfo = 0;
  1250. }
  1251. WVTAsn1InfoFree(SpcMinimalCriteria_PDU, pOssInfo);
  1252. return fResult;
  1253. }
  1254. //+-------------------------------------------------------------------------
  1255. // SPC Financial Criteria Info Encode (OSS X509)
  1256. //--------------------------------------------------------------------------
  1257. BOOL WINAPI WVTAsn1SpcFinancialCriteriaInfoEncode(
  1258. IN DWORD dwCertEncodingType,
  1259. IN LPCSTR lpszStructType,
  1260. IN PSPC_FINANCIAL_CRITERIA pInfo,
  1261. OUT BYTE *pbEncoded,
  1262. IN OUT DWORD *pcbEncoded
  1263. )
  1264. {
  1265. SpcFinancialCriteria OssInfo;
  1266. OssInfo.financialInfoAvailable =
  1267. (ossBoolean) pInfo->fFinancialInfoAvailable;
  1268. OssInfo.meetsCriteria = (ossBoolean) pInfo->fMeetsCriteria;
  1269. return WVTAsn1InfoEncode(
  1270. SpcFinancialCriteria_PDU,
  1271. &OssInfo,
  1272. pbEncoded,
  1273. pcbEncoded
  1274. );
  1275. }
  1276. //+-------------------------------------------------------------------------
  1277. // SPC Financial Criteria Info Decode (OSS X509)
  1278. //--------------------------------------------------------------------------
  1279. BOOL WINAPI WVTAsn1SpcFinancialCriteriaInfoDecode(
  1280. IN DWORD dwCertEncodingType,
  1281. IN LPCSTR lpszStructType,
  1282. IN const BYTE *pbEncoded,
  1283. IN DWORD cbEncoded,
  1284. IN DWORD dwFlags,
  1285. OUT PSPC_FINANCIAL_CRITERIA pInfo,
  1286. IN OUT DWORD *pcbInfo
  1287. )
  1288. {
  1289. BOOL fResult;
  1290. SpcFinancialCriteria *pOssInfo = NULL;
  1291. if (pInfo == NULL)
  1292. *pcbInfo = 0;
  1293. if ((fResult = WVTAsn1InfoDecodeAndAlloc(
  1294. SpcFinancialCriteria_PDU,
  1295. pbEncoded,
  1296. cbEncoded,
  1297. (void **) &pOssInfo))) {
  1298. if (*pcbInfo < sizeof(SPC_FINANCIAL_CRITERIA)) {
  1299. if (pInfo) {
  1300. fResult = FALSE;
  1301. SetLastError((DWORD) ERROR_MORE_DATA);
  1302. }
  1303. } else {
  1304. pInfo->fFinancialInfoAvailable =
  1305. (BOOL) pOssInfo->financialInfoAvailable;
  1306. pInfo->fMeetsCriteria = (BOOL) pOssInfo->meetsCriteria;
  1307. }
  1308. *pcbInfo = sizeof(SPC_FINANCIAL_CRITERIA);
  1309. } else
  1310. *pcbInfo = 0;
  1311. WVTAsn1InfoFree(SpcFinancialCriteria_PDU, pOssInfo);
  1312. return fResult;
  1313. }
  1314. //+-------------------------------------------------------------------------
  1315. // SPC statement type attribute value Encode (OSS X509)
  1316. //--------------------------------------------------------------------------
  1317. BOOL WINAPI WVTAsn1SpcStatementTypeEncode(
  1318. IN DWORD dwCertEncodingType,
  1319. IN LPCSTR lpszStructType,
  1320. IN PSPC_STATEMENT_TYPE pInfo,
  1321. OUT BYTE *pbEncoded,
  1322. IN OUT DWORD *pcbEncoded
  1323. )
  1324. {
  1325. BOOL fResult;
  1326. DWORD cId;
  1327. LPSTR *ppszId;
  1328. SpcStatementType OssInfo;
  1329. ObjectID *pOssId;
  1330. cId = pInfo->cKeyPurposeId;
  1331. ppszId = pInfo->rgpszKeyPurposeId;
  1332. OssInfo.count = cId;
  1333. OssInfo.value = NULL;
  1334. if (cId > 0) {
  1335. pOssId = (ObjectID *) SpcAsnAlloc(cId * sizeof(ObjectID));
  1336. if (pOssId == NULL)
  1337. goto ErrorReturn;
  1338. memset(pOssId, 0, cId * sizeof(ObjectID));
  1339. OssInfo.value = pOssId;
  1340. }
  1341. // Array of Object Ids
  1342. for ( ; cId > 0; cId--, ppszId++, pOssId++) {
  1343. if (!WVTAsn1SetObjId(*ppszId, pOssId))
  1344. goto ErrorReturn;
  1345. }
  1346. fResult = WVTAsn1InfoEncode(
  1347. SpcStatementType_PDU,
  1348. &OssInfo,
  1349. pbEncoded,
  1350. pcbEncoded
  1351. );
  1352. goto CommonReturn;
  1353. ErrorReturn:
  1354. *pcbEncoded = 0;
  1355. fResult = FALSE;
  1356. CommonReturn:
  1357. if (OssInfo.value)
  1358. SpcAsnFree(OssInfo.value);
  1359. return fResult;
  1360. }
  1361. //+-------------------------------------------------------------------------
  1362. // SPC statement type attribute value Decode (OSS X509)
  1363. //--------------------------------------------------------------------------
  1364. BOOL WINAPI WVTAsn1SpcStatementTypeDecode(
  1365. IN DWORD dwCertEncodingType,
  1366. IN LPCSTR lpszStructType,
  1367. IN const BYTE *pbEncoded,
  1368. IN DWORD cbEncoded,
  1369. IN DWORD dwFlags,
  1370. OUT PSPC_STATEMENT_TYPE pInfo,
  1371. IN OUT DWORD *pcbInfo
  1372. )
  1373. {
  1374. BOOL fResult;
  1375. SpcStatementType *pOssInfo = NULL;
  1376. BYTE *pbExtra;
  1377. LONG lRemainExtra;
  1378. LONG lAlignExtra;
  1379. DWORD cId;
  1380. LPSTR *ppszId;
  1381. ObjectID *pOssId;
  1382. if (pInfo == NULL)
  1383. *pcbInfo = 0;
  1384. if (!WVTAsn1InfoDecodeAndAlloc(
  1385. SpcStatementType_PDU,
  1386. pbEncoded,
  1387. cbEncoded,
  1388. (void **) &pOssInfo))
  1389. goto ErrorReturn;
  1390. // for lRemainExtra < 0, LENGTH_ONLY calculation
  1391. lRemainExtra = (LONG) *pcbInfo - sizeof(SPC_STATEMENT_TYPE);
  1392. if (lRemainExtra < 0) {
  1393. pbExtra = NULL;
  1394. } else
  1395. pbExtra = (BYTE *) pInfo + sizeof(SPC_STATEMENT_TYPE);
  1396. cId = pOssInfo->count;
  1397. pOssId = pOssInfo->value;
  1398. lAlignExtra = INFO_LEN_ALIGN(cId * sizeof(LPSTR));
  1399. lRemainExtra -= lAlignExtra;
  1400. if (lRemainExtra >= 0) {
  1401. pInfo->cKeyPurposeId = cId;
  1402. ppszId = (LPSTR *) pbExtra;
  1403. pInfo->rgpszKeyPurposeId = ppszId;
  1404. pbExtra += lAlignExtra;
  1405. } else
  1406. ppszId = NULL;
  1407. // Array of Object Ids
  1408. for ( ; cId > 0; cId--, ppszId++, pOssId++) {
  1409. WVTAsn1GetObjId(pOssId, dwFlags, ppszId, &pbExtra, &lRemainExtra);
  1410. }
  1411. if (lRemainExtra >= 0)
  1412. *pcbInfo = *pcbInfo - (DWORD) lRemainExtra;
  1413. else {
  1414. *pcbInfo = *pcbInfo + (DWORD) -lRemainExtra;
  1415. if (pInfo) goto LengthError;
  1416. }
  1417. fResult = TRUE;
  1418. goto CommonReturn;
  1419. LengthError:
  1420. SetLastError((DWORD) ERROR_MORE_DATA);
  1421. fResult = FALSE;
  1422. goto CommonReturn;
  1423. ErrorReturn:
  1424. *pcbInfo = 0;
  1425. fResult = FALSE;
  1426. CommonReturn:
  1427. WVTAsn1InfoFree(SpcStatementType_PDU, pOssInfo);
  1428. return fResult;
  1429. }
  1430. //+-------------------------------------------------------------------------
  1431. // SPC SP Opus info attribute value Encode (OSS X509)
  1432. //--------------------------------------------------------------------------
  1433. BOOL WINAPI WVTAsn1SpcSpOpusInfoEncode(
  1434. IN DWORD dwCertEncodingType,
  1435. IN LPCSTR lpszStructType,
  1436. IN PSPC_SP_OPUS_INFO pInfo,
  1437. OUT BYTE *pbEncoded,
  1438. IN OUT DWORD *pcbEncoded
  1439. )
  1440. {
  1441. BOOL fResult;
  1442. SpcSpOpusInfo OssInfo;
  1443. memset(&OssInfo, 0, sizeof(OssInfo));
  1444. if (pInfo->pwszProgramName) {
  1445. WVTAsn1SetSpcString((LPWSTR) pInfo->pwszProgramName, &OssInfo.programName);
  1446. OssInfo.bit_mask |= programName_present;
  1447. }
  1448. if (pInfo->pMoreInfo) {
  1449. if (!WVTAsn1SetSpcLink(pInfo->pMoreInfo, &OssInfo.moreInfo))
  1450. goto ErrorReturn;
  1451. OssInfo.bit_mask |= moreInfo_present;
  1452. }
  1453. if (pInfo->pPublisherInfo) {
  1454. if (!WVTAsn1SetSpcLink(pInfo->pPublisherInfo, &OssInfo.publisherInfo))
  1455. goto ErrorReturn;
  1456. OssInfo.bit_mask |= publisherInfo_present;
  1457. }
  1458. fResult = WVTAsn1InfoEncode(
  1459. SpcSpOpusInfo_PDU,
  1460. &OssInfo,
  1461. pbEncoded,
  1462. pcbEncoded
  1463. );
  1464. goto CommonReturn;
  1465. ErrorReturn:
  1466. *pcbEncoded = 0;
  1467. fResult = FALSE;
  1468. CommonReturn:
  1469. WVTAsn1FreeSpcLink(&OssInfo.moreInfo);
  1470. WVTAsn1FreeSpcLink(&OssInfo.publisherInfo);
  1471. return fResult;
  1472. }
  1473. //+-------------------------------------------------------------------------
  1474. // SPC SP Opus info attribute value Encode (OSS X509)
  1475. //--------------------------------------------------------------------------
  1476. BOOL WINAPI WVTAsn1SpcSpOpusInfoDecode(
  1477. IN DWORD dwCertEncodingType,
  1478. IN LPCSTR lpszStructType,
  1479. IN const BYTE *pbEncoded,
  1480. IN DWORD cbEncoded,
  1481. IN DWORD dwFlags,
  1482. OUT PSPC_SP_OPUS_INFO pInfo,
  1483. IN OUT DWORD *pcbInfo
  1484. )
  1485. {
  1486. BOOL fResult;
  1487. SpcSpOpusInfo *pOssInfo = NULL;
  1488. BYTE *pbExtra;
  1489. LONG lRemainExtra;
  1490. if (pInfo == NULL)
  1491. *pcbInfo = 0;
  1492. if (!WVTAsn1InfoDecodeAndAlloc(
  1493. SpcSpOpusInfo_PDU,
  1494. pbEncoded,
  1495. cbEncoded,
  1496. (void **) &pOssInfo))
  1497. goto ErrorReturn;
  1498. // for lRemainExtra < 0, LENGTH_ONLY calculation
  1499. lRemainExtra = (LONG) *pcbInfo - sizeof(SPC_SP_OPUS_INFO);
  1500. if (lRemainExtra < 0) {
  1501. pbExtra = NULL;
  1502. } else {
  1503. // Default all optional fields to zero
  1504. memset(pInfo, 0, sizeof(SPC_SP_OPUS_INFO));
  1505. pbExtra = (BYTE *) pInfo + sizeof(SPC_SP_OPUS_INFO);
  1506. }
  1507. if (pOssInfo->bit_mask & programName_present) {
  1508. WVTAsn1GetSpcString(&pOssInfo->programName, dwFlags,
  1509. (LPWSTR*) &pInfo->pwszProgramName, &pbExtra, &lRemainExtra);
  1510. }
  1511. if (pOssInfo->bit_mask & moreInfo_present) {
  1512. if (!WVTAsn1GetSpcLinkPointer(&pOssInfo->moreInfo, dwFlags,
  1513. &pInfo->pMoreInfo, &pbExtra, &lRemainExtra))
  1514. goto ErrorReturn;
  1515. }
  1516. if (pOssInfo->bit_mask & publisherInfo_present) {
  1517. if (!WVTAsn1GetSpcLinkPointer(&pOssInfo->publisherInfo, dwFlags,
  1518. &pInfo->pPublisherInfo, &pbExtra, &lRemainExtra))
  1519. goto ErrorReturn;
  1520. }
  1521. if (lRemainExtra >= 0)
  1522. *pcbInfo = *pcbInfo - (DWORD) lRemainExtra;
  1523. else {
  1524. *pcbInfo = *pcbInfo + (DWORD) -lRemainExtra;
  1525. if (pInfo) goto LengthError;
  1526. }
  1527. fResult = TRUE;
  1528. goto CommonReturn;
  1529. LengthError:
  1530. SetLastError((DWORD) ERROR_MORE_DATA);
  1531. fResult = FALSE;
  1532. goto CommonReturn;
  1533. ErrorReturn:
  1534. *pcbInfo = 0;
  1535. fResult = FALSE;
  1536. CommonReturn:
  1537. WVTAsn1InfoFree(SpcSpOpusInfo_PDU, pOssInfo);
  1538. return fResult;
  1539. }
  1540. BOOL WINAPI WVTAsn1SpcLinkEncode( IN DWORD dwCertEncodingType,
  1541. IN LPCSTR lpszStructType,
  1542. IN PSPC_LINK pInfo,
  1543. OUT BYTE *pbEncoded,
  1544. IN OUT DWORD *pcbEncoded)
  1545. {
  1546. BOOL fResult;
  1547. SpcLink OssSpcLink;
  1548. if (!(WVTAsn1SetSpcLink(pInfo, &OssSpcLink)))
  1549. {
  1550. goto ErrorReturn;
  1551. }
  1552. fResult = WVTAsn1InfoEncode(SpcLink_PDU, &OssSpcLink, pbEncoded,
  1553. pcbEncoded);
  1554. goto CommonReturn;
  1555. ErrorReturn:
  1556. *pcbEncoded = 0;
  1557. fResult = FALSE;
  1558. CommonReturn:
  1559. return(fResult);
  1560. }
  1561. BOOL WINAPI WVTAsn1SpcLinkDecode(IN DWORD dwCertEncodingType,
  1562. IN LPCSTR lpszStructType,
  1563. IN const BYTE *pbEncoded,
  1564. IN DWORD cbEncoded,
  1565. IN DWORD dwFlags,
  1566. OUT PSPC_LINK pInfo,
  1567. IN OUT DWORD *pcbInfo)
  1568. {
  1569. BOOL fResult;
  1570. SpcLink *pSpcLink = NULL;
  1571. BYTE *pbExtra;
  1572. LONG lRemainExtra;
  1573. if (pInfo == NULL)
  1574. {
  1575. *pcbInfo = 0;
  1576. }
  1577. if (!(WVTAsn1InfoDecodeAndAlloc(SpcLink_PDU, pbEncoded, cbEncoded,
  1578. (void **)&pSpcLink)))
  1579. {
  1580. goto ErrorReturn;
  1581. }
  1582. // for lRemainExtra < 0, LENGTH_ONLY calculation
  1583. lRemainExtra = (LONG) *pcbInfo - sizeof(SPC_LINK);
  1584. if (lRemainExtra < 0)
  1585. {
  1586. pbExtra = NULL;
  1587. }
  1588. else
  1589. {
  1590. pbExtra = (BYTE *) pInfo + sizeof(SPC_LINK);
  1591. }
  1592. if (!(WVTAsn1GetSpcLink(pSpcLink, dwFlags, pInfo, &pbExtra, &lRemainExtra)))
  1593. {
  1594. goto ErrorReturn;
  1595. }
  1596. if (lRemainExtra >= 0)
  1597. {
  1598. *pcbInfo = *pcbInfo - (DWORD) lRemainExtra;
  1599. }
  1600. else
  1601. {
  1602. *pcbInfo = *pcbInfo + (DWORD) -lRemainExtra;
  1603. if (pInfo)
  1604. {
  1605. goto LengthError;
  1606. }
  1607. }
  1608. fResult = TRUE;
  1609. goto CommonReturn;
  1610. LengthError:
  1611. SetLastError((DWORD)ERROR_MORE_DATA);
  1612. fResult = FALSE;
  1613. goto CommonReturn;
  1614. ErrorReturn:
  1615. *pcbInfo = 0;
  1616. fResult = FALSE;
  1617. CommonReturn:
  1618. WVTAsn1InfoFree(SpcLink_PDU, pSpcLink);
  1619. return fResult;
  1620. }
  1621. BOOL WINAPI WVTAsn1SpcPeImageDataEncode(IN DWORD dwCertEncodingType,
  1622. IN LPCSTR lpszStructType,
  1623. IN PSPC_PE_IMAGE_DATA pInfo,
  1624. OUT BYTE *pbEncoded,
  1625. IN OUT DWORD *pcbEncoded)
  1626. {
  1627. BOOL fResult;
  1628. SpcPeImageData OssInfo;
  1629. memset(&OssInfo, 0, sizeof(OssInfo));
  1630. if (pInfo->Flags.cbData)
  1631. {
  1632. // SpcPeImageFlags has its own definition. It has a default
  1633. // bit (includeResources). Therefore, can't use the default BITSTRING.
  1634. // Note: BITSTRING's length is an unsigned int, while SpcPeImageFlags's
  1635. // length is an unsigned short.
  1636. BITSTRING OssBitString;
  1637. WVTAsn1SetBit(&pInfo->Flags, &OssBitString);
  1638. OssInfo.flags.length = (WORD)OssBitString.length;
  1639. OssInfo.flags.value = OssBitString.value;
  1640. OssInfo.bit_mask |= flags_present;
  1641. }
  1642. if (pInfo->pFile)
  1643. {
  1644. if (!WVTAsn1SetSpcLink(pInfo->pFile, &OssInfo.file))
  1645. {
  1646. goto ErrorReturn;
  1647. }
  1648. OssInfo.bit_mask |= file_present;
  1649. }
  1650. fResult = WVTAsn1InfoEncode(SpcPeImageData_PDU, &OssInfo, pbEncoded,
  1651. pcbEncoded);
  1652. goto CommonReturn;
  1653. ErrorReturn:
  1654. *pcbEncoded = 0;
  1655. fResult = FALSE;
  1656. CommonReturn:
  1657. WVTAsn1FreeSpcLink(&OssInfo.file);
  1658. return(fResult);
  1659. }
  1660. //+-------------------------------------------------------------------------
  1661. // SPC Portable Executable (PE) Image Attribute Value Decode (OSS X509)
  1662. //--------------------------------------------------------------------------
  1663. BOOL WINAPI WVTAsn1SpcPeImageDataDecode(IN DWORD dwCertEncodingType,
  1664. IN LPCSTR lpszStructType,
  1665. IN const BYTE *pbEncoded,
  1666. IN DWORD cbEncoded,
  1667. IN DWORD dwFlags,
  1668. OUT PSPC_PE_IMAGE_DATA pInfo,
  1669. IN OUT DWORD *pcbInfo)
  1670. {
  1671. BOOL fResult;
  1672. SpcPeImageData *pOssInfo = NULL;
  1673. BYTE *pbExtra;
  1674. LONG lRemainExtra;
  1675. if (pInfo == NULL)
  1676. {
  1677. *pcbInfo = 0;
  1678. }
  1679. if (!WVTAsn1InfoDecodeAndAlloc(SpcPeImageData_PDU, pbEncoded, cbEncoded,
  1680. (void **)&pOssInfo))
  1681. {
  1682. goto ErrorReturn;
  1683. }
  1684. // for lRemainExtra < 0, LENGTH_ONLY calculation
  1685. lRemainExtra = (LONG) *pcbInfo - sizeof(SPC_PE_IMAGE_DATA);
  1686. if (lRemainExtra < 0)
  1687. {
  1688. pbExtra = NULL;
  1689. }
  1690. else
  1691. {
  1692. // Default all optional fields to zero
  1693. memset(pInfo, 0, sizeof(SPC_PE_IMAGE_DATA));
  1694. pbExtra = (BYTE *) pInfo + sizeof(SPC_PE_IMAGE_DATA);
  1695. }
  1696. if (pOssInfo->bit_mask & flags_present)
  1697. {
  1698. // See above encode for why we need to do this extra indirect step
  1699. BITSTRING OssBitString;
  1700. OssBitString.length = pOssInfo->flags.length;
  1701. OssBitString.value = pOssInfo->flags.value;
  1702. WVTAsn1GetBit(&OssBitString, dwFlags,
  1703. &pInfo->Flags, &pbExtra, &lRemainExtra);
  1704. }
  1705. if (pOssInfo->bit_mask & file_present)
  1706. {
  1707. if (!WVTAsn1GetSpcLinkPointer(&pOssInfo->file, dwFlags,
  1708. &pInfo->pFile, &pbExtra, &lRemainExtra))
  1709. {
  1710. goto ErrorReturn;
  1711. }
  1712. }
  1713. if (lRemainExtra >= 0)
  1714. {
  1715. *pcbInfo = *pcbInfo - (DWORD) lRemainExtra;
  1716. }
  1717. else
  1718. {
  1719. *pcbInfo = *pcbInfo + (DWORD) -lRemainExtra;
  1720. if (pInfo)
  1721. {
  1722. goto LengthError;
  1723. }
  1724. }
  1725. fResult = TRUE;
  1726. goto CommonReturn;
  1727. LengthError:
  1728. SetLastError((DWORD) ERROR_MORE_DATA);
  1729. fResult = FALSE;
  1730. goto CommonReturn;
  1731. ErrorReturn:
  1732. *pcbInfo = 0;
  1733. fResult = FALSE;
  1734. CommonReturn:
  1735. WVTAsn1InfoFree(SpcPeImageData_PDU, pOssInfo);
  1736. return(fResult);
  1737. }
  1738. BOOL WINAPI WVTAsn1SpcSigInfoEncode(DWORD dwCertEncodingType, LPCSTR lpszStructType,
  1739. PSPC_SIGINFO pInfo, BYTE *pbEncoded,
  1740. DWORD *pcbEncoded)
  1741. {
  1742. BOOL fResult;
  1743. SpcSigInfo OssSpcSigInfo;
  1744. if (!(WVTAsn1SetSpcSigInfo(pInfo, &OssSpcSigInfo)))
  1745. {
  1746. goto ErrorReturn;
  1747. }
  1748. fResult = WVTAsn1InfoEncode(SpcSigInfo_PDU, &OssSpcSigInfo, pbEncoded,
  1749. pcbEncoded);
  1750. goto CommonReturn;
  1751. ErrorReturn:
  1752. *pcbEncoded = 0;
  1753. fResult = FALSE;
  1754. CommonReturn:
  1755. return(fResult);
  1756. }
  1757. BOOL WINAPI WVTAsn1SpcSigInfoDecode(DWORD dwCertEncodingType, LPCSTR lpszStructType,
  1758. const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
  1759. PSPC_SIGINFO pInfo, OUT DWORD *pcbInfo)
  1760. {
  1761. BOOL fResult;
  1762. SpcSigInfo *pSpcSigInfo = NULL;
  1763. BYTE *pbExtra;
  1764. LONG lRemainExtra;
  1765. if (pInfo == NULL)
  1766. {
  1767. *pcbInfo = 0;
  1768. }
  1769. if (!(WVTAsn1InfoDecodeAndAlloc(SpcSigInfo_PDU, pbEncoded, cbEncoded, (void **)&pSpcSigInfo)))
  1770. {
  1771. goto ErrorReturn;
  1772. }
  1773. // for lRemainExtra < 0, LENGTH_ONLY calculation
  1774. lRemainExtra = (LONG) *pcbInfo - sizeof(SPC_SIGINFO);
  1775. if (lRemainExtra < 0)
  1776. {
  1777. pbExtra = NULL;
  1778. }
  1779. else
  1780. {
  1781. pbExtra = (BYTE *) pInfo + sizeof(SPC_SIGINFO);
  1782. }
  1783. if (!(WVTAsn1GetSpcSigInfo(pSpcSigInfo, dwFlags, pInfo, &pbExtra, &lRemainExtra)))
  1784. {
  1785. goto ErrorReturn;
  1786. }
  1787. if (lRemainExtra >= 0)
  1788. {
  1789. *pcbInfo = *pcbInfo - (DWORD) lRemainExtra;
  1790. }
  1791. else
  1792. {
  1793. *pcbInfo = *pcbInfo + (DWORD) -lRemainExtra;
  1794. if (pInfo)
  1795. {
  1796. goto LengthError;
  1797. }
  1798. }
  1799. fResult = TRUE;
  1800. goto CommonReturn;
  1801. LengthError:
  1802. SetLastError((DWORD)ERROR_MORE_DATA);
  1803. fResult = FALSE;
  1804. goto CommonReturn;
  1805. ErrorReturn:
  1806. *pcbInfo = 0;
  1807. fResult = FALSE;
  1808. CommonReturn:
  1809. WVTAsn1InfoFree(SpcSigInfo_PDU, pSpcSigInfo);
  1810. return fResult;
  1811. }
  1812. BOOL WVTAsn1SetCatNameValue(IN PCAT_NAMEVALUE pInfo, OUT NameValue *pOss)
  1813. {
  1814. memset(pOss, 0x00, sizeof(*pOss));
  1815. // tag!
  1816. WVTAsn1SetBMP(pInfo->pwszTag, &pOss->refname);
  1817. // flags
  1818. pOss->typeaction = (int)pInfo->fdwFlags;
  1819. // value
  1820. WVTAsn1SetOctetString(&pInfo->Value, &pOss->value);
  1821. return(TRUE);
  1822. }
  1823. BOOL WVTAsn1SetCatMemberInfo(IN PCAT_MEMBERINFO pInfo, OUT MemberInfo *pOss)
  1824. {
  1825. memset(pOss, 0x00, sizeof(*pOss));
  1826. // subject guid (wide text)
  1827. WVTAsn1SetBMP(pInfo->pwszSubjGuid, &pOss->subguid);
  1828. // cert version
  1829. pOss->certversion = (int)pInfo->dwCertVersion;
  1830. return(TRUE);
  1831. }
  1832. BOOL WVTAsn1GetCatNameValue(IN NameValue *pOss, IN DWORD dwFlags,
  1833. OUT PCAT_NAMEVALUE pInfo, IN OUT BYTE **ppbExtra,
  1834. IN OUT LONG *plRemainExtra)
  1835. {
  1836. if (*plRemainExtra >= 0)
  1837. {
  1838. memset(pInfo, 0, sizeof(*pInfo));
  1839. }
  1840. WVTAsn1GetOctetString(&pOss->value, dwFlags,
  1841. &pInfo->Value, ppbExtra, plRemainExtra);
  1842. if (*plRemainExtra >= 0)
  1843. {
  1844. pInfo->fdwFlags = (DWORD)pOss->typeaction;
  1845. }
  1846. WVTAsn1GetBMP(&pOss->refname, dwFlags, &pInfo->pwszTag, ppbExtra, plRemainExtra);
  1847. return(TRUE);
  1848. }
  1849. BOOL WVTAsn1GetCatMemberInfo(IN MemberInfo *pOss, IN DWORD dwFlags,
  1850. OUT PCAT_MEMBERINFO pInfo, IN OUT BYTE **ppbExtra,
  1851. IN OUT LONG *plRemainExtra)
  1852. {
  1853. if (*plRemainExtra >= 0)
  1854. {
  1855. memset(pInfo, 0, sizeof(*pInfo));
  1856. }
  1857. WVTAsn1GetBMP(&pOss->subguid, dwFlags, &pInfo->pwszSubjGuid, ppbExtra, plRemainExtra);
  1858. if (*plRemainExtra >= 0)
  1859. {
  1860. pInfo->dwCertVersion = pOss->certversion;
  1861. }
  1862. return(TRUE);
  1863. }
  1864. BOOL WINAPI WVTAsn1CatNameValueEncode( IN DWORD dwCertEncodingType,
  1865. IN LPCSTR lpszStructType,
  1866. IN PCAT_NAMEVALUE pInfo,
  1867. OUT BYTE *pbEncoded,
  1868. IN OUT DWORD *pcbEncoded)
  1869. {
  1870. BOOL fResult;
  1871. NameValue OssNameValue;
  1872. if (!(WVTAsn1SetCatNameValue(pInfo, &OssNameValue)))
  1873. {
  1874. goto ErrorReturn;
  1875. }
  1876. fResult = WVTAsn1InfoEncode(NameValue_PDU, &OssNameValue, pbEncoded,
  1877. pcbEncoded);
  1878. goto CommonReturn;
  1879. ErrorReturn:
  1880. *pcbEncoded = 0;
  1881. fResult = FALSE;
  1882. CommonReturn:
  1883. return(fResult);
  1884. }
  1885. BOOL WINAPI WVTAsn1CatMemberInfoEncode( IN DWORD dwCertEncodingType,
  1886. IN LPCSTR lpszStructType,
  1887. IN PCAT_MEMBERINFO pInfo,
  1888. OUT BYTE *pbEncoded,
  1889. IN OUT DWORD *pcbEncoded)
  1890. {
  1891. BOOL fResult;
  1892. MemberInfo OssMemberInfo;
  1893. if (!(WVTAsn1SetCatMemberInfo(pInfo, &OssMemberInfo)))
  1894. {
  1895. goto ErrorReturn;
  1896. }
  1897. fResult = WVTAsn1InfoEncode(MemberInfo_PDU, &OssMemberInfo, pbEncoded,
  1898. pcbEncoded);
  1899. goto CommonReturn;
  1900. ErrorReturn:
  1901. *pcbEncoded = 0;
  1902. fResult = FALSE;
  1903. CommonReturn:
  1904. return(fResult);
  1905. }
  1906. BOOL WINAPI WVTAsn1CatNameValueDecode(IN DWORD dwCertEncodingType,
  1907. IN LPCSTR lpszStructType,
  1908. IN const BYTE *pbEncoded,
  1909. IN DWORD cbEncoded,
  1910. IN DWORD dwFlags,
  1911. OUT PCAT_NAMEVALUE pInfo,
  1912. IN OUT DWORD *pcbInfo)
  1913. {
  1914. BOOL fResult;
  1915. NameValue *pNameValue = NULL;
  1916. BYTE *pbExtra;
  1917. LONG lRemainExtra;
  1918. if (pInfo == NULL)
  1919. {
  1920. *pcbInfo = 0;
  1921. }
  1922. if (!(WVTAsn1InfoDecodeAndAlloc(NameValue_PDU, pbEncoded, cbEncoded,
  1923. (void **)&pNameValue)))
  1924. {
  1925. goto ErrorReturn;
  1926. }
  1927. // for lRemainExtra < 0, LENGTH_ONLY calculation
  1928. lRemainExtra = (LONG) *pcbInfo - sizeof(CAT_NAMEVALUE);
  1929. if (lRemainExtra < 0)
  1930. {
  1931. pbExtra = NULL;
  1932. }
  1933. else
  1934. {
  1935. pbExtra = (BYTE *) pInfo + sizeof(CAT_NAMEVALUE);
  1936. }
  1937. if (!(WVTAsn1GetCatNameValue(pNameValue, dwFlags, pInfo, &pbExtra, &lRemainExtra)))
  1938. {
  1939. goto ErrorReturn;
  1940. }
  1941. if (lRemainExtra >= 0)
  1942. {
  1943. *pcbInfo = *pcbInfo - (DWORD) lRemainExtra;
  1944. }
  1945. else
  1946. {
  1947. *pcbInfo = *pcbInfo + (DWORD) -lRemainExtra;
  1948. if (pInfo)
  1949. {
  1950. goto LengthError;
  1951. }
  1952. }
  1953. fResult = TRUE;
  1954. goto CommonReturn;
  1955. LengthError:
  1956. SetLastError((DWORD)ERROR_MORE_DATA);
  1957. fResult = FALSE;
  1958. goto CommonReturn;
  1959. ErrorReturn:
  1960. *pcbInfo = 0;
  1961. fResult = FALSE;
  1962. CommonReturn:
  1963. WVTAsn1InfoFree(NameValue_PDU, pNameValue);
  1964. return fResult;
  1965. }
  1966. BOOL WINAPI WVTAsn1CatMemberInfoDecode( IN DWORD dwCertEncodingType,
  1967. IN LPCSTR lpszStructType,
  1968. IN const BYTE *pbEncoded,
  1969. IN DWORD cbEncoded,
  1970. IN DWORD dwFlags,
  1971. OUT PCAT_MEMBERINFO pInfo,
  1972. IN OUT DWORD *pcbInfo)
  1973. {
  1974. BOOL fResult;
  1975. MemberInfo *pMemberInfo = NULL;
  1976. BYTE *pbExtra;
  1977. LONG lRemainExtra;
  1978. if (pInfo == NULL)
  1979. {
  1980. *pcbInfo = 0;
  1981. }
  1982. if (!(WVTAsn1InfoDecodeAndAlloc(MemberInfo_PDU, pbEncoded, cbEncoded,
  1983. (void **)&pMemberInfo)))
  1984. {
  1985. goto ErrorReturn;
  1986. }
  1987. // for lRemainExtra < 0, LENGTH_ONLY calculation
  1988. lRemainExtra = (LONG) *pcbInfo - sizeof(CAT_MEMBERINFO);
  1989. if (lRemainExtra < 0)
  1990. {
  1991. pbExtra = NULL;
  1992. }
  1993. else
  1994. {
  1995. pbExtra = (BYTE *) pInfo + sizeof(CAT_MEMBERINFO);
  1996. }
  1997. if (!(WVTAsn1GetCatMemberInfo(pMemberInfo, dwFlags, pInfo, &pbExtra, &lRemainExtra)))
  1998. {
  1999. goto ErrorReturn;
  2000. }
  2001. if (lRemainExtra >= 0)
  2002. {
  2003. *pcbInfo = *pcbInfo - (DWORD) lRemainExtra;
  2004. }
  2005. else
  2006. {
  2007. *pcbInfo = *pcbInfo + (DWORD) -lRemainExtra;
  2008. if (pInfo)
  2009. {
  2010. goto LengthError;
  2011. }
  2012. }
  2013. fResult = TRUE;
  2014. goto CommonReturn;
  2015. LengthError:
  2016. SetLastError((DWORD)ERROR_MORE_DATA);
  2017. fResult = FALSE;
  2018. goto CommonReturn;
  2019. ErrorReturn:
  2020. *pcbInfo = 0;
  2021. fResult = FALSE;
  2022. CommonReturn:
  2023. WVTAsn1InfoFree(MemberInfo_PDU, pMemberInfo);
  2024. return fResult;
  2025. }