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.

11913 lines
319 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1995 - 1999
  6. //
  7. // File: frmtfunc.cpp
  8. //
  9. // Contents: OID format functions
  10. //
  11. // Functions: CryptFrmtFuncDllMain
  12. // CryptFormatObject
  13. // CryptQueryObject
  14. //
  15. // History: 15-05-97 xiaohs created
  16. // 27 Oct 1999 dsie add post win2k features.
  17. //--------------------------------------------------------------------------
  18. #include "global.hxx"
  19. #include <dbgdef.h>
  20. #include "frmtfunc.h"
  21. HMODULE hFrmtFuncInst;
  22. static HCRYPTOIDFUNCSET hFormatFuncSet;
  23. //function type define
  24. typedef BOOL (WINAPI *PFN_FORMAT_FUNC)(
  25. IN DWORD dwCertEncodingType,
  26. IN DWORD dwFormatType,
  27. IN DWORD dwFormatStrType,
  28. IN void *pFormatStruct,
  29. IN LPCSTR lpszStructType,
  30. IN const BYTE *pbEncoded,
  31. IN DWORD cbEncoded,
  32. OUT void *pbFormat,
  33. IN OUT DWORD *pcbFormat
  34. );
  35. static BOOL
  36. WINAPI
  37. FormatBytesToHex(
  38. DWORD dwCertEncodingType,
  39. DWORD dwFormatType,
  40. DWORD dwFormatStrType,
  41. void *pFormatStruct,
  42. LPCSTR lpszStructType,
  43. const BYTE *pbEncoded,
  44. DWORD cbEncoded,
  45. void *pbFormat,
  46. DWORD *pcbFormat);
  47. static BOOL
  48. WINAPI
  49. CryptDllFormatAttr(
  50. DWORD dwEncodingType,
  51. DWORD dwFormatType,
  52. DWORD dwFormatStrType,
  53. void *pStruct,
  54. LPCSTR lpszStructType,
  55. const BYTE *pbEncoded,
  56. DWORD cbEncoded,
  57. void *pBuffer,
  58. DWORD *pcBuffer);
  59. static BOOL
  60. WINAPI
  61. CryptDllFormatName(
  62. DWORD dwEncodingType,
  63. DWORD dwFormatType,
  64. DWORD dwFormatStrType,
  65. void *pStruct,
  66. LPCSTR lpszStructType,
  67. const BYTE *pbEncoded,
  68. DWORD cbEncoded,
  69. void *pbBuffer,
  70. DWORD *pcbBuffer);
  71. static BOOL
  72. WINAPI
  73. FormatBasicConstraints2(
  74. DWORD dwCertEncodingType,
  75. DWORD dwFormatType,
  76. DWORD dwFormatStrType,
  77. void *pFormatStruct,
  78. LPCSTR lpszStructType,
  79. const BYTE *pbEncoded,
  80. DWORD cbEncoded,
  81. void *pbFormat,
  82. DWORD *pcbFormat);
  83. static BOOL
  84. WINAPI
  85. FormatBasicConstraints(
  86. DWORD dwCertEncodingType,
  87. DWORD dwFormatType,
  88. DWORD dwFormatStrType,
  89. void *pFormatStruct,
  90. LPCSTR lpszStructType,
  91. const BYTE *pbEncoded,
  92. DWORD cbEncoded,
  93. void *pbFormat,
  94. DWORD *pcbFormat);
  95. static BOOL
  96. WINAPI
  97. FormatCRLReasonCode(
  98. DWORD dwCertEncodingType,
  99. DWORD dwFormatType,
  100. DWORD dwFormatStrType,
  101. void *pFormatStruct,
  102. LPCSTR lpszStructType,
  103. const BYTE *pbEncoded,
  104. DWORD cbEncoded,
  105. void *pbFormat,
  106. DWORD *pcbFormat);
  107. static BOOL
  108. WINAPI
  109. FormatEnhancedKeyUsage(
  110. DWORD dwCertEncodingType,
  111. DWORD dwFormatType,
  112. DWORD dwFormatStrType,
  113. void *pFormatStruct,
  114. LPCSTR lpszStructType,
  115. const BYTE *pbEncoded,
  116. DWORD cbEncoded,
  117. void *pbFormat,
  118. DWORD *pcbFormat);
  119. static BOOL
  120. WINAPI
  121. FormatAltName(
  122. DWORD dwCertEncodingType,
  123. DWORD dwFormatType,
  124. DWORD dwFormatStrType,
  125. void *pFormatStruct,
  126. LPCSTR lpszStructType,
  127. const BYTE *pbEncoded,
  128. DWORD cbEncoded,
  129. void *pbFormat,
  130. DWORD *pcbFormat);
  131. static BOOL
  132. WINAPI
  133. FormatAuthorityKeyID(
  134. DWORD dwCertEncodingType,
  135. DWORD dwFormatType,
  136. DWORD dwFormatStrType,
  137. void *pFormatStruct,
  138. LPCSTR lpszStructType,
  139. const BYTE *pbEncoded,
  140. DWORD cbEncoded,
  141. void *pbFormat,
  142. DWORD *pcbFormat);
  143. static BOOL
  144. WINAPI
  145. FormatAuthorityKeyID2(
  146. DWORD dwCertEncodingType,
  147. DWORD dwFormatType,
  148. DWORD dwFormatStrType,
  149. void *pFormatStruct,
  150. LPCSTR lpszStructType,
  151. const BYTE *pbEncoded,
  152. DWORD cbEncoded,
  153. void *pbFormat,
  154. DWORD *pcbFormat);
  155. static BOOL
  156. WINAPI
  157. FormatNextUpdateLocation(
  158. DWORD dwCertEncodingType,
  159. DWORD dwFormatType,
  160. DWORD dwFormatStrType,
  161. void *pFormatStruct,
  162. LPCSTR lpszStructType,
  163. const BYTE *pbEncoded,
  164. DWORD cbEncoded,
  165. void *pbFormat,
  166. DWORD *pcbFormat);
  167. static BOOL
  168. WINAPI
  169. FormatSubjectKeyID(
  170. DWORD dwCertEncodingType,
  171. DWORD dwFormatType,
  172. DWORD dwFormatStrType,
  173. void *pFormatStruct,
  174. LPCSTR lpszStructType,
  175. const BYTE *pbEncoded,
  176. DWORD cbEncoded,
  177. void *pbFormat,
  178. DWORD *pcbFormat);
  179. static BOOL
  180. WINAPI
  181. FormatFinancialCriteria(
  182. DWORD dwCertEncodingType,
  183. DWORD dwFormatType,
  184. DWORD dwFormatStrType,
  185. void *pFormatStruct,
  186. LPCSTR lpszStructType,
  187. const BYTE *pbEncoded,
  188. DWORD cbEncoded,
  189. void *pbFormat,
  190. DWORD *pcbFormat);
  191. static BOOL
  192. WINAPI
  193. FormatSMIMECapabilities(
  194. DWORD dwCertEncodingType,
  195. DWORD dwFormatType,
  196. DWORD dwFormatStrType,
  197. void *pFormatStruct,
  198. LPCSTR lpszStructType,
  199. const BYTE *pbEncoded,
  200. DWORD cbEncoded,
  201. void *pbFormat,
  202. DWORD *pcbFormat);
  203. static BOOL
  204. WINAPI
  205. FormatKeyUsage(
  206. DWORD dwCertEncodingType,
  207. DWORD dwFormatType,
  208. DWORD dwFormatStrType,
  209. void *pFormatStruct,
  210. LPCSTR lpszStructType,
  211. const BYTE *pbEncoded,
  212. DWORD cbEncoded,
  213. void *pbFormat,
  214. DWORD *pcbFormat);
  215. static BOOL
  216. WINAPI
  217. FormatAuthortiyInfoAccess(
  218. DWORD dwCertEncodingType,
  219. DWORD dwFormatType,
  220. DWORD dwFormatStrType,
  221. void *pFormatStruct,
  222. LPCSTR lpszStructType,
  223. const BYTE *pbEncoded,
  224. DWORD cbEncoded,
  225. void *pbFormat,
  226. DWORD *pcbFormat);
  227. static BOOL
  228. WINAPI
  229. FormatKeyAttributes(
  230. DWORD dwCertEncodingType,
  231. DWORD dwFormatType,
  232. DWORD dwFormatStrType,
  233. void *pFormatStruct,
  234. LPCSTR lpszStructType,
  235. const BYTE *pbEncoded,
  236. DWORD cbEncoded,
  237. void *pbFormat,
  238. DWORD *pcbFormat);
  239. static BOOL
  240. WINAPI
  241. FormatKeyRestriction(
  242. DWORD dwCertEncodingType,
  243. DWORD dwFormatType,
  244. DWORD dwFormatStrType,
  245. void *pFormatStruct,
  246. LPCSTR lpszStructType,
  247. const BYTE *pbEncoded,
  248. DWORD cbEncoded,
  249. void *pbFormat,
  250. DWORD *pcbFormat);
  251. static BOOL
  252. WINAPI
  253. FormatCRLDistPoints(
  254. DWORD dwCertEncodingType,
  255. DWORD dwFormatType,
  256. DWORD dwFormatStrType,
  257. void *pFormatStruct,
  258. LPCSTR lpszStructType,
  259. const BYTE *pbEncoded,
  260. DWORD cbEncoded,
  261. void *pbFormat,
  262. DWORD *pcbFormat);
  263. static BOOL
  264. WINAPI
  265. FormatCertPolicies(
  266. DWORD dwCertEncodingType,
  267. DWORD dwFormatType,
  268. DWORD dwFormatStrType,
  269. void *pFormatStruct,
  270. LPCSTR lpszStructType,
  271. const BYTE *pbEncoded,
  272. DWORD cbEncoded,
  273. void *pbFormat,
  274. DWORD *pcbFormat);
  275. static BOOL
  276. WINAPI
  277. FormatCAVersion(
  278. DWORD dwCertEncodingType,
  279. DWORD dwFormatType,
  280. DWORD dwFormatStrType,
  281. void *pFormatStruct,
  282. LPCSTR lpszStructType,
  283. const BYTE *pbEncoded,
  284. DWORD cbEncoded,
  285. void *pbFormat,
  286. DWORD *pcbFormat);
  287. static BOOL
  288. WINAPI
  289. FormatAnyUnicodeStringExtension(
  290. DWORD dwCertEncodingType,
  291. DWORD dwFormatType,
  292. DWORD dwFormatStrType,
  293. void *pFormatStruct,
  294. LPCSTR lpszStructType,
  295. const BYTE *pbEncoded,
  296. DWORD cbEncoded,
  297. void *pbFormat,
  298. DWORD *pcbFormat);
  299. static BOOL
  300. WINAPI
  301. FormatAnyNameValueStringAttr(
  302. DWORD dwCertEncodingType,
  303. DWORD dwFormatType,
  304. DWORD dwFormatStrType,
  305. void *pFormatStruct,
  306. LPCSTR lpszStructType,
  307. const BYTE *pbEncoded,
  308. DWORD cbEncoded,
  309. void *pbFormat,
  310. DWORD *pcbFormat);
  311. static BOOL
  312. WINAPI
  313. FormatNetscapeCertType(
  314. DWORD dwCertEncodingType,
  315. DWORD dwFormatType,
  316. DWORD dwFormatStrType,
  317. void *pFormatStruct,
  318. LPCSTR lpszStructType,
  319. const BYTE *pbEncoded,
  320. DWORD cbEncoded,
  321. void *pbFormat,
  322. DWORD *pcbFormat);
  323. static BOOL
  324. WINAPI
  325. FormatSPAgencyInfo(
  326. DWORD dwCertEncodingType,
  327. DWORD dwFormatType,
  328. DWORD dwFormatStrType,
  329. void *pFormatStruct,
  330. LPCSTR lpszStructType,
  331. const BYTE *pbEncoded,
  332. DWORD cbEncoded,
  333. void *pbFormat,
  334. DWORD *pcbFormat);
  335. //
  336. // DSIE: Post Win2K.
  337. //
  338. static BOOL
  339. WINAPI
  340. FormatCrlNumber (
  341. DWORD dwCertEncodingType,
  342. DWORD dwFormatType,
  343. DWORD dwFormatStrType,
  344. void *pFormatStruct,
  345. LPCSTR lpszStructType,
  346. const BYTE *pbEncoded,
  347. DWORD cbEncoded,
  348. void *pbFormat,
  349. DWORD *pcbFormat);
  350. static BOOL
  351. WINAPI
  352. FormatCrlNextPublish (
  353. DWORD dwCertEncodingType,
  354. DWORD dwFormatType,
  355. DWORD dwFormatStrType,
  356. void *pFormatStruct,
  357. LPCSTR lpszStructType,
  358. const BYTE *pbEncoded,
  359. DWORD cbEncoded,
  360. void *pbFormat,
  361. DWORD *pcbFormat);
  362. static BOOL
  363. WINAPI
  364. FormatIssuingDistPoint (
  365. DWORD dwCertEncodingType,
  366. DWORD dwFormatType,
  367. DWORD dwFormatStrType,
  368. void *pFormatStruct,
  369. LPCSTR lpszStructType,
  370. const BYTE *pbEncoded,
  371. DWORD cbEncoded,
  372. void *pbFormat,
  373. DWORD *pcbFormat);
  374. static BOOL
  375. WINAPI
  376. FormatNameConstraints (
  377. DWORD dwCertEncodingType,
  378. DWORD dwFormatType,
  379. DWORD dwFormatStrType,
  380. void *pFormatStruct,
  381. LPCSTR lpszStructType,
  382. const BYTE *pbEncoded,
  383. DWORD cbEncoded,
  384. void *pbFormat,
  385. DWORD *pcbFormat);
  386. static BOOL
  387. WINAPI
  388. FormatCertSrvPreviousCertHash (
  389. DWORD dwCertEncodingType,
  390. DWORD dwFormatType,
  391. DWORD dwFormatStrType,
  392. void *pFormatStruct,
  393. LPCSTR lpszStructType,
  394. const BYTE *pbEncoded,
  395. DWORD cbEncoded,
  396. void *pbFormat,
  397. DWORD *pcbFormat);
  398. static BOOL
  399. WINAPI
  400. FormatPolicyMappings (
  401. DWORD dwCertEncodingType,
  402. DWORD dwFormatType,
  403. DWORD dwFormatStrType,
  404. void *pFormatStruct,
  405. LPCSTR lpszStructType,
  406. const BYTE *pbEncoded,
  407. DWORD cbEncoded,
  408. void *pbFormat,
  409. DWORD *pcbFormat);
  410. static BOOL
  411. WINAPI
  412. FormatPolicyConstraints (
  413. DWORD dwCertEncodingType,
  414. DWORD dwFormatType,
  415. DWORD dwFormatStrType,
  416. void *pFormatStruct,
  417. LPCSTR lpszStructType,
  418. const BYTE *pbEncoded,
  419. DWORD cbEncoded,
  420. void *pbFormat,
  421. DWORD *pcbFormat);
  422. static BOOL
  423. WINAPI
  424. FormatCertificateTemplate (
  425. DWORD dwCertEncodingType,
  426. DWORD dwFormatType,
  427. DWORD dwFormatStrType,
  428. void *pFormatStruct,
  429. LPCSTR lpszStructType,
  430. const BYTE *pbEncoded,
  431. DWORD cbEncoded,
  432. void *pbFormat,
  433. DWORD *pcbFormat);
  434. static BOOL
  435. WINAPI
  436. FormatXCertDistPoints(
  437. DWORD dwCertEncodingType,
  438. DWORD dwFormatType,
  439. DWORD dwFormatStrType,
  440. void *pFormatStruct,
  441. LPCSTR lpszStructType,
  442. const BYTE *pbEncoded,
  443. DWORD cbEncoded,
  444. void *pbFormat,
  445. DWORD *pcbFormat);
  446. static const CRYPT_OID_FUNC_ENTRY DefaultFormatTable[] = {
  447. CRYPT_DEFAULT_OID, FormatBytesToHex};
  448. static const CRYPT_OID_FUNC_ENTRY OIDFormatTable[] = {
  449. szOID_COMMON_NAME, CryptDllFormatAttr,
  450. szOID_SUR_NAME, CryptDllFormatAttr,
  451. szOID_DEVICE_SERIAL_NUMBER, CryptDllFormatAttr,
  452. szOID_COUNTRY_NAME, CryptDllFormatAttr,
  453. szOID_LOCALITY_NAME, CryptDllFormatAttr,
  454. szOID_STATE_OR_PROVINCE_NAME, CryptDllFormatAttr,
  455. szOID_STREET_ADDRESS, CryptDllFormatAttr,
  456. szOID_ORGANIZATION_NAME, CryptDllFormatAttr,
  457. szOID_ORGANIZATIONAL_UNIT_NAME, CryptDllFormatAttr,
  458. szOID_TITLE, CryptDllFormatAttr,
  459. szOID_DESCRIPTION, CryptDllFormatAttr,
  460. szOID_SEARCH_GUIDE, CryptDllFormatAttr,
  461. szOID_BUSINESS_CATEGORY, CryptDllFormatAttr,
  462. szOID_POSTAL_ADDRESS, CryptDllFormatAttr,
  463. szOID_POSTAL_CODE, CryptDllFormatAttr,
  464. szOID_POST_OFFICE_BOX, CryptDllFormatAttr,
  465. szOID_PHYSICAL_DELIVERY_OFFICE_NAME, CryptDllFormatAttr,
  466. szOID_TELEPHONE_NUMBER, CryptDllFormatAttr,
  467. szOID_TELEX_NUMBER, CryptDllFormatAttr,
  468. szOID_TELETEXT_TERMINAL_IDENTIFIER, CryptDllFormatAttr,
  469. szOID_FACSIMILE_TELEPHONE_NUMBER, CryptDllFormatAttr,
  470. szOID_X21_ADDRESS, CryptDllFormatAttr,
  471. szOID_INTERNATIONAL_ISDN_NUMBER, CryptDllFormatAttr,
  472. szOID_REGISTERED_ADDRESS, CryptDllFormatAttr,
  473. szOID_DESTINATION_INDICATOR, CryptDllFormatAttr,
  474. szOID_PREFERRED_DELIVERY_METHOD, CryptDllFormatAttr,
  475. szOID_PRESENTATION_ADDRESS, CryptDllFormatAttr,
  476. szOID_SUPPORTED_APPLICATION_CONTEXT, CryptDllFormatAttr,
  477. szOID_MEMBER, CryptDllFormatAttr,
  478. szOID_OWNER, CryptDllFormatAttr,
  479. szOID_ROLE_OCCUPANT, CryptDllFormatAttr,
  480. szOID_SEE_ALSO, CryptDllFormatAttr,
  481. szOID_USER_PASSWORD, CryptDllFormatAttr,
  482. szOID_USER_CERTIFICATE, CryptDllFormatAttr,
  483. szOID_CA_CERTIFICATE, CryptDllFormatAttr,
  484. szOID_AUTHORITY_REVOCATION_LIST, CryptDllFormatAttr,
  485. szOID_CERTIFICATE_REVOCATION_LIST, CryptDllFormatAttr,
  486. szOID_CROSS_CERTIFICATE_PAIR, CryptDllFormatAttr,
  487. szOID_GIVEN_NAME, CryptDllFormatAttr,
  488. szOID_INITIALS, CryptDllFormatAttr,
  489. szOID_DOMAIN_COMPONENT, CryptDllFormatAttr,
  490. szOID_PKCS_12_FRIENDLY_NAME_ATTR, CryptDllFormatAttr,
  491. szOID_PKCS_12_LOCAL_KEY_ID, CryptDllFormatAttr,
  492. X509_NAME, CryptDllFormatName,
  493. X509_UNICODE_NAME, CryptDllFormatName,
  494. szOID_BASIC_CONSTRAINTS2, FormatBasicConstraints2,
  495. X509_BASIC_CONSTRAINTS2, FormatBasicConstraints2,
  496. szOID_BASIC_CONSTRAINTS, FormatBasicConstraints,
  497. X509_BASIC_CONSTRAINTS, FormatBasicConstraints,
  498. szOID_CRL_REASON_CODE, FormatCRLReasonCode,
  499. X509_CRL_REASON_CODE, FormatCRLReasonCode,
  500. szOID_ENHANCED_KEY_USAGE, FormatEnhancedKeyUsage,
  501. X509_ENHANCED_KEY_USAGE, FormatEnhancedKeyUsage,
  502. szOID_SUBJECT_ALT_NAME, FormatAltName,
  503. szOID_ISSUER_ALT_NAME, FormatAltName,
  504. szOID_SUBJECT_ALT_NAME2, FormatAltName,
  505. szOID_ISSUER_ALT_NAME2, FormatAltName,
  506. X509_ALTERNATE_NAME, FormatAltName,
  507. szOID_AUTHORITY_KEY_IDENTIFIER, FormatAuthorityKeyID,
  508. X509_AUTHORITY_KEY_ID, FormatAuthorityKeyID,
  509. szOID_AUTHORITY_KEY_IDENTIFIER2, FormatAuthorityKeyID2,
  510. X509_AUTHORITY_KEY_ID2, FormatAuthorityKeyID2,
  511. szOID_NEXT_UPDATE_LOCATION, FormatNextUpdateLocation,
  512. szOID_SUBJECT_KEY_IDENTIFIER, FormatSubjectKeyID,
  513. SPC_FINANCIAL_CRITERIA_OBJID, FormatFinancialCriteria,
  514. SPC_FINANCIAL_CRITERIA_STRUCT, FormatFinancialCriteria,
  515. szOID_RSA_SMIMECapabilities, FormatSMIMECapabilities,
  516. PKCS_SMIME_CAPABILITIES, FormatSMIMECapabilities,
  517. szOID_KEY_USAGE, FormatKeyUsage,
  518. X509_KEY_USAGE, FormatKeyUsage,
  519. szOID_AUTHORITY_INFO_ACCESS, FormatAuthortiyInfoAccess,
  520. X509_AUTHORITY_INFO_ACCESS, FormatAuthortiyInfoAccess,
  521. szOID_KEY_ATTRIBUTES, FormatKeyAttributes,
  522. X509_KEY_ATTRIBUTES, FormatKeyAttributes,
  523. szOID_KEY_USAGE_RESTRICTION, FormatKeyRestriction,
  524. X509_KEY_USAGE_RESTRICTION, FormatKeyRestriction,
  525. szOID_CRL_DIST_POINTS, FormatCRLDistPoints,
  526. X509_CRL_DIST_POINTS, FormatCRLDistPoints,
  527. szOID_FRESHEST_CRL, FormatCRLDistPoints, // Post Win2K
  528. szOID_CERT_POLICIES, FormatCertPolicies,
  529. X509_CERT_POLICIES, FormatCertPolicies,
  530. szOID_ENROLL_CERTTYPE_EXTENSION, FormatAnyUnicodeStringExtension,
  531. szOID_OS_VERSION, FormatAnyUnicodeStringExtension,
  532. szOID_NETSCAPE_CERT_TYPE, FormatNetscapeCertType,
  533. szOID_NETSCAPE_BASE_URL, FormatAnyUnicodeStringExtension,
  534. szOID_NETSCAPE_REVOCATION_URL, FormatAnyUnicodeStringExtension,
  535. szOID_NETSCAPE_CA_REVOCATION_URL, FormatAnyUnicodeStringExtension,
  536. szOID_NETSCAPE_CERT_RENEWAL_URL, FormatAnyUnicodeStringExtension,
  537. szOID_NETSCAPE_CA_POLICY_URL, FormatAnyUnicodeStringExtension,
  538. szOID_NETSCAPE_SSL_SERVER_NAME, FormatAnyUnicodeStringExtension,
  539. szOID_NETSCAPE_COMMENT, FormatAnyUnicodeStringExtension,
  540. szOID_ENROLLMENT_NAME_VALUE_PAIR, FormatAnyNameValueStringAttr,
  541. szOID_CERTSRV_CA_VERSION, FormatCAVersion,
  542. SPC_SP_AGENCY_INFO_OBJID, FormatSPAgencyInfo,
  543. SPC_SP_AGENCY_INFO_STRUCT, FormatSPAgencyInfo,
  544. // Post Win2K
  545. szOID_CRL_NUMBER, FormatCrlNumber,
  546. szOID_DELTA_CRL_INDICATOR, FormatCrlNumber,
  547. szOID_CRL_VIRTUAL_BASE, FormatCrlNumber,
  548. szOID_CRL_NEXT_PUBLISH, FormatCrlNextPublish,
  549. szOID_ISSUING_DIST_POINT, FormatIssuingDistPoint,
  550. X509_ISSUING_DIST_POINT, FormatIssuingDistPoint,
  551. szOID_NAME_CONSTRAINTS, FormatNameConstraints,
  552. X509_NAME_CONSTRAINTS, FormatNameConstraints,
  553. szOID_CERTSRV_PREVIOUS_CERT_HASH, FormatCertSrvPreviousCertHash,
  554. szOID_APPLICATION_CERT_POLICIES, FormatCertPolicies,
  555. X509_POLICY_MAPPINGS, FormatPolicyMappings,
  556. szOID_POLICY_MAPPINGS, FormatPolicyMappings,
  557. szOID_APPLICATION_POLICY_MAPPINGS, FormatPolicyMappings,
  558. X509_POLICY_CONSTRAINTS, FormatPolicyConstraints,
  559. szOID_POLICY_CONSTRAINTS, FormatPolicyConstraints,
  560. szOID_APPLICATION_POLICY_CONSTRAINTS, FormatPolicyConstraints,
  561. X509_CERTIFICATE_TEMPLATE, FormatCertificateTemplate,
  562. szOID_CERTIFICATE_TEMPLATE, FormatCertificateTemplate,
  563. szOID_CRL_SELF_CDP, FormatCRLDistPoints,
  564. X509_CROSS_CERT_DIST_POINTS, FormatXCertDistPoints,
  565. szOID_CROSS_CERT_DIST_POINTS, FormatXCertDistPoints,
  566. };
  567. DWORD dwOIDFormatCount = sizeof(OIDFormatTable) / sizeof(OIDFormatTable[0]);
  568. //+-------------------------------------------------------------------------
  569. // Dll initialization
  570. //--------------------------------------------------------------------------
  571. BOOL
  572. WINAPI
  573. CryptFrmtFuncDllMain(
  574. HMODULE hModule,
  575. DWORD fdwReason,
  576. LPVOID lpReserved)
  577. {
  578. BOOL fRet;
  579. switch (fdwReason) {
  580. case DLL_PROCESS_ATTACH:
  581. hFrmtFuncInst = hModule;
  582. if (NULL == (hFormatFuncSet = CryptInitOIDFunctionSet(
  583. CRYPT_OID_FORMAT_OBJECT_FUNC,
  584. 0))) // dwFlags
  585. goto CryptInitFrmtFuncError;
  586. //install the default formatting routine
  587. if (!CryptInstallOIDFunctionAddress(
  588. NULL, // hModule
  589. X509_ASN_ENCODING,
  590. CRYPT_OID_FORMAT_OBJECT_FUNC,
  591. 1,
  592. DefaultFormatTable,
  593. 0)) // dwFlags
  594. goto CryptInstallFrmtFuncError;
  595. //install the OID formatting routine
  596. if (!CryptInstallOIDFunctionAddress(
  597. NULL, // hModule
  598. X509_ASN_ENCODING,
  599. CRYPT_OID_FORMAT_OBJECT_FUNC,
  600. dwOIDFormatCount,
  601. OIDFormatTable,
  602. 0)) // dwFlags
  603. goto CryptInstallFrmtFuncError;
  604. break;
  605. case DLL_PROCESS_DETACH:
  606. case DLL_THREAD_DETACH:
  607. default:
  608. break;
  609. }
  610. fRet = TRUE;
  611. CommonReturn:
  612. return fRet;
  613. ErrorReturn:
  614. fRet = FALSE;
  615. goto CommonReturn;
  616. TRACE_ERROR(CryptInitFrmtFuncError)
  617. TRACE_ERROR(CryptInstallFrmtFuncError)
  618. }
  619. //------------------------------------------------------------------------
  620. // Convert the byte to its Hex presentation.
  621. //
  622. // Precondition: byte is less than 15
  623. //
  624. //------------------------------------------------------------------------
  625. ULONG ByteToHex(BYTE byte, LPWSTR wszZero, LPWSTR wszA)
  626. {
  627. ULONG uValue=0;
  628. if(((ULONG)byte)<=9)
  629. {
  630. uValue=((ULONG)byte)+ULONG(*wszZero);
  631. }
  632. else
  633. {
  634. uValue=(ULONG)byte-10+ULONG(*wszA);
  635. }
  636. return uValue;
  637. }
  638. //--------------------------------------------------------------------------
  639. //
  640. // Format the encoded bytes into a hex string in the format of
  641. // xxxx xxxx xxxx xxxx ...
  642. //
  643. // DSIE 6/28/2000: change format to xx xx xx xx, per VicH's request.
  644. //--------------------------------------------------------------------------
  645. static BOOL
  646. WINAPI
  647. FormatBytesToHex(
  648. DWORD dwCertEncodingType,
  649. DWORD dwFormatType,
  650. DWORD dwFormatStrType,
  651. void *pFormatStruct,
  652. LPCSTR lpszStructType,
  653. const BYTE *pbEncoded,
  654. DWORD cbEncoded,
  655. void *pbFormat,
  656. DWORD *pcbFormat)
  657. {
  658. LPWSTR pwszBuffer=NULL;
  659. DWORD dwBufferSize=0;
  660. DWORD dwBufferIndex=0;
  661. DWORD dwEncodedIndex=0;
  662. WCHAR wszSpace[CHAR_SIZE];
  663. WCHAR wszZero[CHAR_SIZE];
  664. WCHAR wszA[CHAR_SIZE];
  665. WCHAR wszHex[HEX_SIZE];
  666. //check for input parameters
  667. if(( pbEncoded!=NULL && cbEncoded==0)
  668. ||(pbEncoded==NULL && cbEncoded!=0)
  669. || (pcbFormat==NULL))
  670. {
  671. SetLastError((DWORD) E_INVALIDARG);
  672. return FALSE;
  673. }
  674. #if (0) // DSIE: Fix bug 128630.
  675. //check for simple case. No work needed
  676. if(pbEncoded==NULL && cbEncoded==0)
  677. {
  678. *pcbFormat=0;
  679. return TRUE;
  680. }
  681. #endif
  682. //calculate the memory needed, in bytes
  683. //we need 3 wchars per byte, along with the NULL terminator
  684. dwBufferSize=sizeof(WCHAR)*(cbEncoded*3+1);
  685. //length only calculation
  686. if(pcbFormat!=NULL && pbFormat==NULL)
  687. {
  688. *pcbFormat=dwBufferSize;
  689. return TRUE;
  690. }
  691. //load the string
  692. if(!LoadStringU(hFrmtFuncInst, IDS_FRMT_SPACE, wszSpace,
  693. CHAR_SIZE)
  694. ||!LoadStringU(hFrmtFuncInst, IDS_FRMT_ZERO, wszZero,
  695. CHAR_SIZE)
  696. ||!LoadStringU(hFrmtFuncInst, IDS_FRMT_A, wszA,
  697. CHAR_SIZE)
  698. ||!LoadStringU(hFrmtFuncInst, IDS_FRMT_HEX, wszHex,
  699. HEX_SIZE)
  700. )
  701. {
  702. SetLastError((DWORD) E_UNEXPECTED);
  703. return FALSE;
  704. }
  705. pwszBuffer=(LPWSTR)malloc(dwBufferSize);
  706. if(!pwszBuffer)
  707. {
  708. SetLastError((DWORD) E_OUTOFMEMORY);
  709. return FALSE;
  710. }
  711. dwBufferIndex=0;
  712. //format the wchar buffer one byte at a time
  713. for(dwEncodedIndex=0; dwEncodedIndex<cbEncoded; dwEncodedIndex++)
  714. {
  715. #if (0) // DSIE:
  716. //copy the space between every two bytes. Skip for the 1st byte
  717. if((0!=dwEncodedIndex) && (0==(dwEncodedIndex % 2)))
  718. #else
  719. //copy the space between every byte. Skip for the 1st byte
  720. if(dwEncodedIndex != 0)
  721. #endif
  722. {
  723. pwszBuffer[dwBufferIndex]=wszSpace[0];
  724. dwBufferIndex++;
  725. }
  726. //format the higher 4 bits
  727. pwszBuffer[dwBufferIndex]=(WCHAR)ByteToHex(
  728. (BYTE)( (pbEncoded[dwEncodedIndex]&UPPER_BITS)>>4 ),
  729. wszZero, wszA);
  730. dwBufferIndex++;
  731. //format the lower 4 bits
  732. pwszBuffer[dwBufferIndex]=(WCHAR)ByteToHex(
  733. (BYTE)( pbEncoded[dwEncodedIndex]&LOWER_BITS ),
  734. wszZero, wszA);
  735. dwBufferIndex++;
  736. }
  737. //add the NULL terminator to the string
  738. pwszBuffer[dwBufferIndex]=wszSpace[1];
  739. //calculate the real size for the buffer
  740. dwBufferSize=sizeof(WCHAR)*(wcslen(pwszBuffer)+1);
  741. //copy the buffer
  742. memcpy(pbFormat, pwszBuffer,
  743. (*pcbFormat>=dwBufferSize) ? dwBufferSize : *pcbFormat);
  744. free(pwszBuffer);
  745. //make sure the user has supplied enough memory
  746. if(*pcbFormat < dwBufferSize)
  747. {
  748. *pcbFormat=dwBufferSize;
  749. SetLastError((DWORD) ERROR_MORE_DATA);
  750. return FALSE;
  751. }
  752. *pcbFormat=dwBufferSize;
  753. return TRUE;
  754. }
  755. //+-----------------------------------------------------------------------------
  756. //
  757. // AllocateAnsiToUnicode
  758. //
  759. //------------------------------------------------------------------------------
  760. static BOOL
  761. WINAPI
  762. AllocateAnsiToUnicode(
  763. LPCSTR pszAnsi,
  764. LPWSTR * ppwszUnicode)
  765. {
  766. BOOL fResult = FALSE;
  767. LPWSTR pwszUnicode = NULL;
  768. DWORD dwWideSize = 0;
  769. if (!ppwszUnicode)
  770. {
  771. goto InvalidArg;
  772. }
  773. *ppwszUnicode = NULL;
  774. if (!pszAnsi)
  775. {
  776. return TRUE;
  777. }
  778. if (!(dwWideSize = MultiByteToWideChar(CP_ACP,
  779. 0,
  780. pszAnsi,
  781. strlen(pszAnsi),
  782. NULL,
  783. 0)))
  784. {
  785. goto szTOwszError;
  786. }
  787. //
  788. // Allocate memory, including the NULL terminator.
  789. //
  790. if (!(pwszUnicode = (WCHAR *) malloc(sizeof(WCHAR) * (dwWideSize + 1))))
  791. {
  792. goto MemoryError;
  793. }
  794. memset(pwszUnicode, 0, sizeof(WCHAR) * (dwWideSize + 1));
  795. if (!MultiByteToWideChar(CP_ACP,
  796. 0,
  797. pszAnsi,
  798. strlen(pszAnsi),
  799. pwszUnicode,
  800. dwWideSize))
  801. {
  802. free(pwszUnicode);
  803. goto szTOwszError;
  804. }
  805. *ppwszUnicode = pwszUnicode;
  806. fResult = TRUE;
  807. CommonReturn:
  808. return fResult;
  809. ErrorReturn:
  810. fResult=FALSE;
  811. goto CommonReturn;
  812. SET_ERROR(InvalidArg,E_INVALIDARG);
  813. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  814. TRACE_ERROR(szTOwszError);
  815. }
  816. //+-----------------------------------------------------------------------------
  817. //
  818. // FormatObjectId
  819. //
  820. //------------------------------------------------------------------------------
  821. static BOOL
  822. WINAPI
  823. FormatObjectId (
  824. LPSTR pszObjId,
  825. DWORD dwGroupId,
  826. BOOL bMultiLines,
  827. LPWSTR * ppwszFormat)
  828. {
  829. BOOL fResult;
  830. PCCRYPT_OID_INFO pOIDInfo = NULL;
  831. LPWSTR pwszObjId = NULL;
  832. //
  833. // Initialize.
  834. //
  835. *ppwszFormat = NULL;
  836. //
  837. // Convert OID to Unicode.
  838. //
  839. if (!AllocateAnsiToUnicode(pszObjId, &pwszObjId))
  840. {
  841. goto AnsiToUnicodeError;
  842. }
  843. //
  844. // Find OID info.
  845. //
  846. if (pOIDInfo = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
  847. (void *) pszObjId,
  848. dwGroupId))
  849. {
  850. //
  851. // "%1!s!(%2!s!)%3!s!"
  852. //
  853. if (!FormatMessageUnicode(ppwszFormat,
  854. IDS_GENERIC_OBJECT_ID,
  855. pOIDInfo->pwszName,
  856. pwszObjId,
  857. bMultiLines ? wszCRLF : wszEMPTY))
  858. {
  859. goto FormatMessageError;
  860. }
  861. }
  862. else
  863. {
  864. //
  865. // "%1!s!%2!s!"
  866. //
  867. if (!FormatMessageUnicode(ppwszFormat,
  868. IDS_STRING,
  869. pwszObjId,
  870. bMultiLines ? wszCRLF : wszEMPTY))
  871. {
  872. goto FormatMessageError;
  873. }
  874. }
  875. fResult = TRUE;
  876. CommonReturn:
  877. if (pwszObjId)
  878. {
  879. free(pwszObjId);
  880. }
  881. return fResult;
  882. ErrorReturn:
  883. fResult = FALSE;
  884. goto CommonReturn;
  885. TRACE_ERROR(AnsiToUnicodeError);
  886. TRACE_ERROR(FormatMessageError);
  887. }
  888. //+-----------------------------------------------------------------------------
  889. //
  890. // FormatIPAddress
  891. //
  892. //------------------------------------------------------------------------------
  893. static BOOL
  894. WINAPI
  895. FormatIPAddress(
  896. DWORD dwCertEncodingType,
  897. DWORD dwFormatType,
  898. DWORD dwFormatStrType,
  899. void *pFormatStruct,
  900. LPCSTR lpszStructType,
  901. UINT idsPrefix,
  902. const BYTE *pbEncoded,
  903. DWORD cbEncoded,
  904. void *pbFormat,
  905. DWORD *pcbFormat)
  906. {
  907. BOOL fResult;
  908. DWORD cbNeeded = 0;
  909. LPWSTR pwszFormat = NULL;
  910. WCHAR wszPrefix[PRE_FIX_SIZE] = wszEMPTY;
  911. BOOL bMultiLines = dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE;
  912. //
  913. // Check for input parameters.
  914. //
  915. if ((pbEncoded!=NULL && cbEncoded==0) ||
  916. (pbEncoded==NULL && cbEncoded!=0) ||
  917. (pcbFormat==NULL))
  918. {
  919. goto InvalidArg;
  920. }
  921. if (bMultiLines && idsPrefix)
  922. {
  923. if(!LoadStringU(hFrmtFuncInst,
  924. idsPrefix,
  925. wszPrefix,
  926. sizeof(wszPrefix) / sizeof(wszPrefix[0])))
  927. {
  928. goto LoadStringError;
  929. }
  930. }
  931. switch (cbEncoded)
  932. {
  933. case 4:
  934. {
  935. //
  936. // "%1!d!.%2!d!.%3!d!.%4!d!"
  937. //
  938. if (!FormatMessageUnicode(&pwszFormat,
  939. IDS_IPADDRESS_V4_4,
  940. (DWORD) pbEncoded[0],
  941. (DWORD) pbEncoded[1],
  942. (DWORD) pbEncoded[2],
  943. (DWORD) pbEncoded[3]))
  944. {
  945. goto FormatMessageError;
  946. }
  947. break;
  948. }
  949. case 8:
  950. {
  951. //
  952. // "%1!d!.%2!d!.%3!d!.%4!d!%5!s!%6!s!Mask=%7!d!.%8!d!.%9!d!.%10!d!"
  953. //
  954. if (!FormatMessageUnicode(&pwszFormat,
  955. IDS_IPADDRESS_V4_8,
  956. (DWORD) pbEncoded[0],
  957. (DWORD) pbEncoded[1],
  958. (DWORD) pbEncoded[2],
  959. (DWORD) pbEncoded[3],
  960. bMultiLines ? wszCRLF : wszEMPTY,
  961. bMultiLines ? wszPrefix : wszCOMMA,
  962. (DWORD) pbEncoded[4],
  963. (DWORD) pbEncoded[5],
  964. (DWORD) pbEncoded[6],
  965. (DWORD) pbEncoded[7]))
  966. {
  967. goto FormatMessageError;
  968. }
  969. break;
  970. }
  971. case 16:
  972. {
  973. //
  974. // "%1!02x!%2!02x!:%3!02x!%4!02x!:%5!02x!%6!02x!:%7!02x!%8!02x!:%9!02x!%10!02x!:%11!02x!%12!02x!:%13!02x!%14!02x!:%15!02x!%16!02x!"
  975. //
  976. if (!FormatMessageUnicode(&pwszFormat,
  977. IDS_IPADDRESS_V6_16,
  978. (DWORD) pbEncoded[0],
  979. (DWORD) pbEncoded[1],
  980. (DWORD) pbEncoded[2],
  981. (DWORD) pbEncoded[3],
  982. (DWORD) pbEncoded[4],
  983. (DWORD) pbEncoded[5],
  984. (DWORD) pbEncoded[6],
  985. (DWORD) pbEncoded[7],
  986. (DWORD) pbEncoded[8],
  987. (DWORD) pbEncoded[9],
  988. (DWORD) pbEncoded[10],
  989. (DWORD) pbEncoded[11],
  990. (DWORD) pbEncoded[12],
  991. (DWORD) pbEncoded[13],
  992. (DWORD) pbEncoded[14],
  993. (DWORD) pbEncoded[15]))
  994. {
  995. goto FormatMessageError;
  996. }
  997. break;
  998. }
  999. case 32:
  1000. {
  1001. //
  1002. // "%1!02x!%2!02x!:%3!02x!%4!02x!:%5!02x!%6!02x!:%7!02x!%8!02x!:%9!02x!%10!02x!:%11!02x!%12!02x!:%13!02x!%14!02x!:%15!02x!%16!02x!%17!s!%18!s!
  1003. // Mask=%19!02x!%20!02x!:%21!02x!%22!02x!:%23!02x!%24!02x!:%25!02x!%26!02x!:%27!02x!%28!02x!:%29!02x!%30!02x!:%31!02x!%32!02x!:%33!02x!%34!02x!"
  1004. //
  1005. if (!FormatMessageUnicode(&pwszFormat,
  1006. IDS_IPADDRESS_V6_32,
  1007. (DWORD) pbEncoded[0],
  1008. (DWORD) pbEncoded[1],
  1009. (DWORD) pbEncoded[2],
  1010. (DWORD) pbEncoded[3],
  1011. (DWORD) pbEncoded[4],
  1012. (DWORD) pbEncoded[5],
  1013. (DWORD) pbEncoded[6],
  1014. (DWORD) pbEncoded[7],
  1015. (DWORD) pbEncoded[8],
  1016. (DWORD) pbEncoded[9],
  1017. (DWORD) pbEncoded[10],
  1018. (DWORD) pbEncoded[11],
  1019. (DWORD) pbEncoded[12],
  1020. (DWORD) pbEncoded[13],
  1021. (DWORD) pbEncoded[14],
  1022. (DWORD) pbEncoded[15],
  1023. bMultiLines ? wszCRLF : wszEMPTY,
  1024. bMultiLines ? wszPrefix : wszCOMMA,
  1025. (DWORD) pbEncoded[16],
  1026. (DWORD) pbEncoded[17],
  1027. (DWORD) pbEncoded[18],
  1028. (DWORD) pbEncoded[19],
  1029. (DWORD) pbEncoded[20],
  1030. (DWORD) pbEncoded[21],
  1031. (DWORD) pbEncoded[22],
  1032. (DWORD) pbEncoded[23],
  1033. (DWORD) pbEncoded[24],
  1034. (DWORD) pbEncoded[25],
  1035. (DWORD) pbEncoded[26],
  1036. (DWORD) pbEncoded[27],
  1037. (DWORD) pbEncoded[28],
  1038. (DWORD) pbEncoded[29],
  1039. (DWORD) pbEncoded[30],
  1040. (DWORD) pbEncoded[31]))
  1041. {
  1042. goto FormatMessageError;
  1043. }
  1044. break;
  1045. }
  1046. default:
  1047. {
  1048. if (!(fResult = FormatBytesToHex(dwCertEncodingType,
  1049. dwFormatType,
  1050. dwFormatStrType,
  1051. pFormatStruct,
  1052. lpszStructType,
  1053. pbEncoded,
  1054. cbEncoded,
  1055. pbFormat,
  1056. pcbFormat)))
  1057. {
  1058. goto FormatBytesToHexError;
  1059. }
  1060. goto CommonReturn;
  1061. }
  1062. }
  1063. //
  1064. // Total length needed.
  1065. //
  1066. cbNeeded = sizeof(WCHAR) * (wcslen(pwszFormat) + 1);
  1067. //
  1068. // Length only calculation?
  1069. //
  1070. if (NULL == pbFormat)
  1071. {
  1072. *pcbFormat = cbNeeded;
  1073. goto SuccessReturn;
  1074. }
  1075. //
  1076. // Caller provided us with enough memory?
  1077. //
  1078. if (*pcbFormat < cbNeeded)
  1079. {
  1080. *pcbFormat = cbNeeded;
  1081. goto MoreDataError;
  1082. }
  1083. //
  1084. // Copy size and data.
  1085. //
  1086. memcpy(pbFormat, pwszFormat, cbNeeded);
  1087. *pcbFormat = cbNeeded;
  1088. SuccessReturn:
  1089. fResult = TRUE;
  1090. CommonReturn:
  1091. if (pwszFormat)
  1092. {
  1093. LocalFree((HLOCAL) pwszFormat);
  1094. }
  1095. return fResult;
  1096. ErrorReturn:
  1097. fResult=FALSE;
  1098. goto CommonReturn;
  1099. SET_ERROR(InvalidArg,E_INVALIDARG);
  1100. TRACE_ERROR(LoadStringError);
  1101. TRACE_ERROR(FormatMessageError);
  1102. TRACE_ERROR(FormatBytesToHexError);
  1103. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  1104. }
  1105. //+-------------------------------------------------------------------------
  1106. // format the specified data structure according to the certificate
  1107. // encoding type.
  1108. //--------------------------------------------------------------------------
  1109. BOOL
  1110. WINAPI
  1111. CryptFormatObject(
  1112. IN DWORD dwCertEncodingType,
  1113. IN DWORD dwFormatType,
  1114. IN DWORD dwFormatStrType,
  1115. IN void *pFormatStruct,
  1116. IN LPCSTR lpszStructType,
  1117. IN const BYTE *pbEncoded,
  1118. IN DWORD cbEncoded,
  1119. OUT void *pbFormat,
  1120. IN OUT DWORD *pcbFormat
  1121. )
  1122. {
  1123. BOOL fResult=FALSE;
  1124. void *pvFuncAddr;
  1125. HCRYPTOIDFUNCADDR hFuncAddr;
  1126. if (CryptGetOIDFunctionAddress(
  1127. hFormatFuncSet,
  1128. dwCertEncodingType,
  1129. lpszStructType,
  1130. 0, // dwFlags
  1131. &pvFuncAddr,
  1132. &hFuncAddr))
  1133. {
  1134. fResult = ((PFN_FORMAT_FUNC) pvFuncAddr)(
  1135. dwCertEncodingType,
  1136. dwFormatType,
  1137. dwFormatStrType,
  1138. pFormatStruct,
  1139. lpszStructType,
  1140. pbEncoded,
  1141. cbEncoded,
  1142. pbFormat,
  1143. pcbFormat
  1144. );
  1145. CryptFreeOIDFunctionAddress(hFuncAddr, 0);
  1146. }
  1147. else
  1148. {
  1149. //do not call the default hex dump if CRYPT_FORMAT_STR_NO_HEX is set
  1150. if(0==(dwFormatStrType & CRYPT_FORMAT_STR_NO_HEX))
  1151. {
  1152. //call the default routine automatically
  1153. if (CryptGetOIDFunctionAddress(
  1154. hFormatFuncSet,
  1155. dwCertEncodingType,
  1156. CRYPT_DEFAULT_OID,
  1157. 0, // dwFlags
  1158. &pvFuncAddr,
  1159. &hFuncAddr))
  1160. {
  1161. fResult = ((PFN_FORMAT_FUNC) pvFuncAddr)(
  1162. dwCertEncodingType,
  1163. dwFormatType,
  1164. dwFormatStrType,
  1165. pFormatStruct,
  1166. lpszStructType,
  1167. pbEncoded,
  1168. cbEncoded,
  1169. pbFormat,
  1170. pcbFormat);
  1171. CryptFreeOIDFunctionAddress(hFuncAddr, 0);
  1172. }
  1173. else
  1174. {
  1175. *pcbFormat = 0;
  1176. fResult = FALSE;
  1177. }
  1178. }
  1179. else
  1180. {
  1181. *pcbFormat = 0;
  1182. fResult = FALSE;
  1183. }
  1184. }
  1185. return fResult;
  1186. }
  1187. //-----------------------------------------------------------
  1188. //
  1189. // This is the actual format routine for an particular RDN attribute.
  1190. //
  1191. // lpszStructType is any OID for CERT_RDN_ATTR. pbEncoded is
  1192. // an encoded BLOB for CERT_NAME_INFO struct. When pBuffer==NULL,
  1193. // *pcbBuffer return the size of memory to be allocated in bytes.
  1194. // Please notice the string is not NULL terminated.
  1195. //
  1196. // For example, to ask for an unicode string of common name,
  1197. // pass lpszStructType=szOID_COMMON_NAME,
  1198. // pass dwFormatType==CRYPT_FORMAT_SIMPL,
  1199. // pBuffer will be set the L"[email protected]".
  1200. //
  1201. //
  1202. //-------------------------------------------------------------
  1203. static BOOL WINAPI CryptDllFormatAttr(
  1204. DWORD dwEncodingType,
  1205. DWORD dwFormatType,
  1206. DWORD dwFormatStrType,
  1207. void *pStruct,
  1208. LPCSTR lpszStructType,
  1209. const BYTE *pbEncoded,
  1210. DWORD cbEncoded,
  1211. void *pBuffer,
  1212. DWORD *pcbBuffer)
  1213. {
  1214. BOOL fResult=FALSE;
  1215. WCHAR *pwszSeperator=NULL;
  1216. BOOL fHeader=FALSE;
  1217. BOOL flengthOnly=FALSE;
  1218. DWORD dwBufferCount=0;
  1219. DWORD dwBufferLimit=0;
  1220. DWORD dwBufferIncrement=0;
  1221. DWORD dwSeperator=0;
  1222. DWORD dwHeader=0;
  1223. DWORD dwOIDSize=0;
  1224. WCHAR *pwszBuffer=NULL;
  1225. WCHAR *pwszHeader=NULL;
  1226. BOOL fAddSeperator=FALSE;
  1227. DWORD cbStructInfo=0;
  1228. CERT_NAME_INFO *pStructInfo=NULL;
  1229. DWORD dwRDNIndex=0;
  1230. DWORD dwAttrIndex=0;
  1231. DWORD dwAttrCount=0;
  1232. CERT_RDN_ATTR *pCertRDNAttr=NULL;
  1233. PCCRYPT_OID_INFO pOIDInfo=NULL;
  1234. LPWSTR pwszTemp;
  1235. //check input parameters
  1236. if(lpszStructType==NULL ||
  1237. (pbEncoded==NULL && cbEncoded!=0) ||
  1238. pcbBuffer==NULL
  1239. )
  1240. goto InvalidArg;
  1241. if(cbEncoded==0)
  1242. {
  1243. *pcbBuffer=0;
  1244. goto InvalidArg;
  1245. }
  1246. //get the seperator of the attributes
  1247. //wszCOMMA is the default seperator
  1248. if(dwFormatType & CRYPT_FORMAT_COMMA)
  1249. pwszSeperator=wszCOMMA;
  1250. else
  1251. {
  1252. if(dwFormatType & CRYPT_FORMAT_SEMICOLON)
  1253. pwszSeperator=wszSEMICOLON;
  1254. else
  1255. {
  1256. if(dwFormatType & CRYPT_FORMAT_CRLF)
  1257. pwszSeperator=wszCRLF;
  1258. else
  1259. {
  1260. pwszSeperator=wszPLUS;
  1261. }
  1262. }
  1263. }
  1264. //calculate the length of the seperator
  1265. dwSeperator=wcslen(pwszSeperator)*sizeof(WCHAR);
  1266. //check the requirement for the header
  1267. if(dwFormatType & CRYPT_FORMAT_X509 ||
  1268. dwFormatType & CRYPT_FORMAT_OID)
  1269. {
  1270. fHeader=TRUE;
  1271. }
  1272. if(NULL==pBuffer)
  1273. flengthOnly=TRUE;
  1274. //decode the X509_UNICODE_NAME
  1275. if(!CryptDecodeObject(dwEncodingType, X509_UNICODE_NAME,
  1276. pbEncoded, cbEncoded, CRYPT_DECODE_NOCOPY_FLAG,
  1277. NULL, &cbStructInfo))
  1278. goto DecodeError;
  1279. //allocate memory
  1280. pStructInfo=(CERT_NAME_INFO *)malloc(cbStructInfo);
  1281. if(!pStructInfo)
  1282. goto MemoryError;
  1283. //decode the struct
  1284. if(!CryptDecodeObject(dwEncodingType, X509_UNICODE_NAME,
  1285. pbEncoded, cbEncoded, CRYPT_DECODE_NOCOPY_FLAG,
  1286. pStructInfo, &cbStructInfo))
  1287. goto DecodeError;
  1288. //allocate the buffer for formatting
  1289. if(!flengthOnly)
  1290. {
  1291. pwszBuffer=(WCHAR *)malloc(g_AllocateSize);
  1292. if(!pwszBuffer)
  1293. goto MemoryError;
  1294. dwBufferLimit=g_AllocateSize;
  1295. }
  1296. //search for the OID requested. If found one, put it
  1297. //to the buffer. If no requested attribut is found,
  1298. //return.
  1299. for(dwRDNIndex=0; dwRDNIndex<pStructInfo->cRDN; dwRDNIndex++)
  1300. {
  1301. //the following line is for code optimization
  1302. dwAttrCount=(pStructInfo->rgRDN)[dwRDNIndex].cRDNAttr;
  1303. for(dwAttrIndex=0; dwAttrIndex<dwAttrCount; dwAttrIndex++)
  1304. {
  1305. //look for the specific OIDs in the function
  1306. if(_stricmp(lpszStructType,
  1307. (pStructInfo->rgRDN)[dwRDNIndex].rgRDNAttr[dwAttrIndex].pszObjId)==0)
  1308. {
  1309. pCertRDNAttr=&((pStructInfo->rgRDN)[dwRDNIndex].rgRDNAttr[dwAttrIndex]);
  1310. //init the dwBufferIncrement
  1311. dwBufferIncrement=0;
  1312. //get the header of the tag
  1313. if(fHeader)
  1314. {
  1315. if(dwFormatType & CRYPT_FORMAT_X509)
  1316. {
  1317. //get the OID's name
  1318. pOIDInfo=CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
  1319. (void *)lpszStructType,
  1320. CRYPT_RDN_ATTR_OID_GROUP_ID);
  1321. if(pOIDInfo)
  1322. {
  1323. //allocate memory, including the NULL terminator
  1324. pwszHeader=(WCHAR *)malloc((wcslen(pOIDInfo->pwszName)+wcslen(wszEQUAL)+1)*
  1325. sizeof(WCHAR));
  1326. if(!pwszHeader)
  1327. goto MemoryError;
  1328. wcscpy(pwszHeader,pOIDInfo->pwszName);
  1329. }
  1330. }
  1331. //use the OID is no mapping is found or
  1332. //OID is requested in the header
  1333. if(pwszHeader==NULL)
  1334. {
  1335. //get the wide character string to the OID
  1336. if(!(dwOIDSize=MultiByteToWideChar(CP_ACP,0,
  1337. lpszStructType,strlen(lpszStructType),NULL,0)))
  1338. goto szTOwszError;
  1339. //allocate memory, including the NULL terminator
  1340. pwszHeader=(WCHAR *)malloc((dwOIDSize+wcslen(wszEQUAL)+1)*
  1341. sizeof(WCHAR));
  1342. if(!pwszHeader)
  1343. goto MemoryError;
  1344. if(!(dwHeader=MultiByteToWideChar(CP_ACP,0,
  1345. lpszStructType,strlen(lpszStructType),pwszHeader,dwOIDSize)))
  1346. goto szTOwszError;
  1347. //NULL terminate the string
  1348. *(pwszHeader+dwHeader)=L'\0';
  1349. }
  1350. //add the euqal sign
  1351. wcscat(pwszHeader, wszEQUAL);
  1352. //get the header size, in bytes, excluding the NULL terminator
  1353. dwHeader=wcslen(pwszHeader)*sizeof(WCHAR);
  1354. dwBufferIncrement+=dwHeader;
  1355. }
  1356. //allocate enough memory. Including the NULL terminator
  1357. dwBufferIncrement+=pCertRDNAttr->Value.cbData;
  1358. dwBufferIncrement+=dwSeperator;
  1359. dwBufferIncrement+=2;
  1360. if(!flengthOnly && ((dwBufferCount+dwBufferIncrement)>dwBufferLimit))
  1361. {
  1362. //reallocate the memory
  1363. #if (0) // DSIE: Bug 27436
  1364. pwszBuffer=(WCHAR *)realloc(pwszBuffer,
  1365. max(dwBufferLimit+g_AllocateSize,
  1366. dwBufferLimit+dwBufferIncrement));
  1367. if(!pwszBuffer)
  1368. goto MemoryError;
  1369. #endif
  1370. pwszTemp=(WCHAR *)realloc(pwszBuffer,
  1371. max(dwBufferLimit+g_AllocateSize,
  1372. dwBufferLimit+dwBufferIncrement));
  1373. if(!pwszTemp)
  1374. goto MemoryError;
  1375. pwszBuffer = pwszTemp;
  1376. dwBufferLimit+=max(g_AllocateSize,dwBufferIncrement);
  1377. }
  1378. //add the header if necessary
  1379. if(fHeader)
  1380. {
  1381. if(!flengthOnly)
  1382. {
  1383. memcpy((BYTE *)(pwszBuffer+dwBufferCount/sizeof(WCHAR)),
  1384. pwszHeader,dwHeader);
  1385. }
  1386. dwBufferCount+=dwHeader;
  1387. //do not need to do header anymore
  1388. fHeader=FALSE;
  1389. }
  1390. //add the seperator after the 1st iteration
  1391. if(fAddSeperator)
  1392. {
  1393. if(!flengthOnly)
  1394. {
  1395. memcpy((BYTE *)(pwszBuffer+dwBufferCount/sizeof(WCHAR)),
  1396. pwszSeperator,dwSeperator);
  1397. }
  1398. dwBufferCount+=dwSeperator;
  1399. }
  1400. else
  1401. fAddSeperator=TRUE;
  1402. //add the attr content
  1403. if(!flengthOnly)
  1404. {
  1405. memcpy((BYTE *)(pwszBuffer+dwBufferCount/sizeof(WCHAR)),
  1406. (pCertRDNAttr->Value.pbData),
  1407. pCertRDNAttr->Value.cbData);
  1408. }
  1409. //increment the buffercount
  1410. dwBufferCount+=pCertRDNAttr->Value.cbData;
  1411. }
  1412. }
  1413. }
  1414. //return the result as requested
  1415. //check if the requested OID is actually in the DN
  1416. if(0==dwBufferCount)
  1417. {
  1418. *pcbBuffer=dwBufferCount;
  1419. goto NotFoundError;
  1420. }
  1421. //we need to NULL terminate the string
  1422. if(!flengthOnly)
  1423. *(pwszBuffer+dwBufferCount/sizeof(WCHAR))=L'\0';
  1424. dwBufferCount+=2;
  1425. if(pBuffer==NULL)
  1426. {
  1427. *pcbBuffer=dwBufferCount;
  1428. fResult=TRUE;
  1429. goto CommonReturn;
  1430. }
  1431. if((*pcbBuffer)<dwBufferCount)
  1432. {
  1433. *pcbBuffer=dwBufferCount;
  1434. goto MoreDataError;
  1435. }
  1436. *pcbBuffer=dwBufferCount;
  1437. memcpy(pBuffer, pwszBuffer,dwBufferCount);
  1438. fResult=TRUE;
  1439. CommonReturn:
  1440. if(pwszHeader)
  1441. free(pwszHeader);
  1442. if(pwszBuffer)
  1443. free(pwszBuffer);
  1444. if(pStructInfo)
  1445. free(pStructInfo);
  1446. return fResult;
  1447. ErrorReturn:
  1448. fResult = FALSE;
  1449. goto CommonReturn;
  1450. SET_ERROR(InvalidArg, E_INVALIDARG);
  1451. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  1452. TRACE_ERROR(DecodeError);
  1453. TRACE_ERROR(szTOwszError);
  1454. SET_ERROR(NotFoundError, E_FAIL);
  1455. SET_ERROR(MoreDataError, ERROR_MORE_DATA);
  1456. }
  1457. //-----------------------------------------------------------
  1458. //
  1459. // This is the actual format routine for an complete CERT_NAME
  1460. //
  1461. //
  1462. // lpszStructType should be X509_NAME pbEncoded is
  1463. // an encoded BLOB for CERT_NAME_INFO struct. When pBuffer==NULL,
  1464. // *pcbBuffer return the size of memory to be allocated in bytes.
  1465. // Please notice the string is NULL terminated.
  1466. //
  1467. //-------------------------------------------------------------
  1468. static BOOL WINAPI CryptDllFormatName(
  1469. DWORD dwEncodingType,
  1470. DWORD dwFormatType,
  1471. DWORD dwFormatStrType,
  1472. void *pStruct,
  1473. LPCSTR lpszStructType,
  1474. const BYTE *pbEncoded,
  1475. DWORD cbEncoded,
  1476. void *pbBuffer,
  1477. DWORD *pcbBuffer)
  1478. {
  1479. //makesure lpszStructType is X509_NAME or X509_UNICODE_NAME
  1480. if((X509_NAME != lpszStructType) &&
  1481. (X509_UNICODE_NAME != lpszStructType))
  1482. {
  1483. SetLastError((DWORD) E_INVALIDARG);
  1484. return FALSE;
  1485. }
  1486. //check input parameters
  1487. if((pbEncoded==NULL && cbEncoded!=0) || pcbBuffer==NULL)
  1488. {
  1489. SetLastError((DWORD) E_INVALIDARG);
  1490. return FALSE;
  1491. }
  1492. if(cbEncoded==0)
  1493. {
  1494. SetLastError((DWORD) E_INVALIDARG);
  1495. return FALSE;
  1496. }
  1497. //call CryptDllFormatNameAll with no prefix
  1498. return CryptDllFormatNameAll(dwEncodingType,
  1499. dwFormatType,
  1500. dwFormatStrType,
  1501. pStruct,
  1502. 0,
  1503. FALSE,
  1504. pbEncoded,
  1505. cbEncoded,
  1506. &pbBuffer,
  1507. pcbBuffer);
  1508. }
  1509. //-----------------------------------------------------------
  1510. //
  1511. // This is the actual format routine for an complete CERT_NAME
  1512. //
  1513. //
  1514. // lpszStructType should be X509_NAME pbEncoded is
  1515. // an encoded BLOB for CERT_NAME_INFO struct. When pBuffer==NULL,
  1516. // *pcbBuffer return the size of memory to be allocated in bytes.
  1517. // Please notice the string is NULL terminated.
  1518. //
  1519. //-------------------------------------------------------------
  1520. BOOL CryptDllFormatNameAll(
  1521. DWORD dwEncodingType,
  1522. DWORD dwFormatType,
  1523. DWORD dwFormatStrType,
  1524. void *pStruct,
  1525. UINT idsPreFix,
  1526. BOOL fToAllocate,
  1527. const BYTE *pbEncoded,
  1528. DWORD cbEncoded,
  1529. void **ppbBuffer,
  1530. DWORD *pcbBuffer)
  1531. {
  1532. BOOL fResult=FALSE;
  1533. DWORD dwStrType=0;
  1534. CERT_NAME_BLOB Cert_Name_Blob;
  1535. DWORD dwSize=0;
  1536. LPWSTR pwszName=NULL;
  1537. LPWSTR pwszMulti=NULL;
  1538. Cert_Name_Blob.cbData=cbEncoded;
  1539. Cert_Name_Blob.pbData=(BYTE *)pbEncoded;
  1540. //calculate the dwStryType to use for CertNameToStrW
  1541. dwStrType=FormatToStr(dwFormatType);
  1542. //overwrite dwStrType to default if we are doing MULTI line format
  1543. //since the options will be ignored
  1544. //We want to use + and , for the seperator
  1545. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  1546. {
  1547. dwStrType &=~(CERT_NAME_STR_CRLF_FLAG);
  1548. dwStrType &=~(CERT_NAME_STR_COMMA_FLAG);
  1549. dwStrType &=~(CERT_NAME_STR_SEMICOLON_FLAG);
  1550. dwStrType &=~(CERT_NAME_STR_NO_QUOTING_FLAG);
  1551. dwStrType &=~(CERT_NAME_STR_NO_PLUS_FLAG);
  1552. }
  1553. //if this function is not called from CryptDllFormatName,
  1554. //make sure that we use the RESERSE Flag
  1555. if(TRUE == fToAllocate)
  1556. dwStrType |= CERT_NAME_STR_REVERSE_FLAG;
  1557. //call the CertNameToStrW to convert
  1558. dwSize=CertNameToStrW(dwEncodingType,
  1559. &Cert_Name_Blob,
  1560. dwStrType,
  1561. NULL,
  1562. 0);
  1563. if(0==dwSize)
  1564. goto CertNameToStrError;
  1565. pwszName=(LPWSTR)malloc(sizeof(WCHAR)*(dwSize));
  1566. if(NULL==pwszName)
  1567. goto MemoryError;
  1568. dwSize=CertNameToStrW(dwEncodingType,
  1569. &Cert_Name_Blob,
  1570. dwStrType,
  1571. pwszName,
  1572. dwSize);
  1573. if(0==dwSize)
  1574. goto CertNameToStrError;
  1575. //we do not need to parse the string for single line format
  1576. if(0==(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
  1577. {
  1578. //calculate the bytes needed
  1579. dwSize=sizeof(WCHAR)*(wcslen(pwszName)+1);
  1580. //if FALSE==fToAllocate, we do not allocate the memory on user's
  1581. //behalf; otherwize, allocate memory to eliminate the need for
  1582. //double call
  1583. if(FALSE==fToAllocate)
  1584. {
  1585. if(NULL==(*ppbBuffer))
  1586. {
  1587. *pcbBuffer=dwSize;
  1588. fResult=TRUE;
  1589. goto CommonReturn;
  1590. }
  1591. if(*pcbBuffer < dwSize)
  1592. {
  1593. *pcbBuffer=dwSize;
  1594. goto MoreDataError;
  1595. }
  1596. memcpy(*ppbBuffer, pwszName, dwSize);
  1597. *pcbBuffer=dwSize;
  1598. }
  1599. else
  1600. {
  1601. *ppbBuffer=malloc(dwSize);
  1602. if(NULL==(*ppbBuffer))
  1603. goto MemoryError;
  1604. memcpy(*ppbBuffer, pwszName, dwSize);
  1605. //pcbBuffer can be NULL in this case
  1606. }
  1607. }
  1608. else
  1609. {
  1610. //we need to parse the string to make the multiple format
  1611. if(!GetCertNameMulti(pwszName, idsPreFix, &pwszMulti))
  1612. goto GetCertNameError;
  1613. //calculate the bytes needee
  1614. dwSize=sizeof(WCHAR)*(wcslen(pwszMulti)+1);
  1615. //if FALSE==fToAllocate, we do not allocate the memory on user's
  1616. //behalf; otherwize, allocate memory to eliminate the need for
  1617. //double call
  1618. if(FALSE==fToAllocate)
  1619. {
  1620. if(NULL==(*ppbBuffer))
  1621. {
  1622. *pcbBuffer=dwSize;
  1623. fResult=TRUE;
  1624. goto CommonReturn;
  1625. }
  1626. if(*pcbBuffer < dwSize)
  1627. {
  1628. *pcbBuffer=dwSize;
  1629. goto MoreDataError;
  1630. }
  1631. memcpy(*ppbBuffer, pwszMulti, dwSize);
  1632. *pcbBuffer=dwSize;
  1633. }
  1634. else
  1635. {
  1636. *ppbBuffer=malloc(dwSize);
  1637. if(NULL==(*ppbBuffer))
  1638. goto MemoryError;
  1639. memcpy(*ppbBuffer, pwszMulti, dwSize);
  1640. //pcbBuffer can be NULL in this case
  1641. }
  1642. }
  1643. fResult=TRUE;
  1644. CommonReturn:
  1645. if(pwszName)
  1646. free(pwszName);
  1647. if(pwszMulti)
  1648. free(pwszMulti);
  1649. return fResult;
  1650. ErrorReturn:
  1651. fResult=FALSE;
  1652. goto CommonReturn;
  1653. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  1654. TRACE_ERROR(CertNameToStrError);
  1655. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  1656. TRACE_ERROR(GetCertNameError);
  1657. }
  1658. //--------------------------------------------------------------------------
  1659. //
  1660. // FormatBasicConstraints2: szOID_BASIC_CONSTRAINTS2
  1661. // X509_BASIC_CONSTRAINTS2
  1662. //--------------------------------------------------------------------------
  1663. static BOOL
  1664. WINAPI
  1665. FormatBasicConstraints2(
  1666. DWORD dwCertEncodingType,
  1667. DWORD dwFormatType,
  1668. DWORD dwFormatStrType,
  1669. void *pFormatStruct,
  1670. LPCSTR lpszStructType,
  1671. const BYTE *pbEncoded,
  1672. DWORD cbEncoded,
  1673. void *pbFormat,
  1674. DWORD *pcbFormat)
  1675. {
  1676. LPWSTR pwszFormat=NULL;
  1677. WCHAR wszSubject[SUBJECT_SIZE];
  1678. WCHAR wszNone[NONE_SIZE];
  1679. PCERT_BASIC_CONSTRAINTS2_INFO pInfo=NULL;
  1680. DWORD cbNeeded=0;
  1681. BOOL fResult=FALSE;
  1682. UINT idsSub=0;
  1683. //check for input parameters
  1684. if((NULL==pbEncoded&& cbEncoded!=0) ||
  1685. (NULL==pcbFormat))
  1686. goto InvalidArg;
  1687. if(cbEncoded==0)
  1688. {
  1689. *pcbFormat=0;
  1690. goto InvalidArg;
  1691. }
  1692. if (!DecodeGenericBLOB(dwCertEncodingType,X509_BASIC_CONSTRAINTS2,
  1693. pbEncoded,cbEncoded, (void **)&pInfo))
  1694. goto DecodeGenericError;
  1695. //load the string for the subjectType
  1696. if (pInfo->fCA)
  1697. idsSub=IDS_SUB_CA;
  1698. else
  1699. idsSub=IDS_SUB_EE;
  1700. if(!LoadStringU(hFrmtFuncInst,idsSub, wszSubject, sizeof(wszSubject)/sizeof(wszSubject[0])))
  1701. goto LoadStringError;
  1702. if (pInfo->fPathLenConstraint)
  1703. {
  1704. //decide between signle line and multi line display
  1705. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  1706. idsSub=IDS_BASIC_CONS2_PATH_MULTI;
  1707. else
  1708. idsSub=IDS_BASIC_CONS2_PATH;
  1709. if(!FormatMessageUnicode(&pwszFormat,idsSub,
  1710. wszSubject, pInfo->dwPathLenConstraint))
  1711. goto FormatMsgError;
  1712. }
  1713. else
  1714. {
  1715. if(!LoadStringU(hFrmtFuncInst,IDS_NONE, wszNone, sizeof(wszNone)/sizeof(wszNone[0])))
  1716. goto LoadStringError;
  1717. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  1718. idsSub=IDS_BASIC_CONS2_NONE_MULTI;
  1719. else
  1720. idsSub=IDS_BASIC_CONS2_NONE;
  1721. if(!FormatMessageUnicode(&pwszFormat,idsSub,
  1722. wszSubject, wszNone))
  1723. goto FormatMsgError;
  1724. }
  1725. cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
  1726. //length only calculation
  1727. if(NULL==pbFormat)
  1728. {
  1729. *pcbFormat=cbNeeded;
  1730. fResult=TRUE;
  1731. goto CommonReturn;
  1732. }
  1733. if((*pcbFormat)<cbNeeded)
  1734. {
  1735. *pcbFormat=cbNeeded;
  1736. goto MoreDataError;
  1737. }
  1738. //copy the data
  1739. memcpy(pbFormat, pwszFormat, cbNeeded);
  1740. //copy the size
  1741. *pcbFormat=cbNeeded;
  1742. fResult=TRUE;
  1743. CommonReturn:
  1744. if(pwszFormat)
  1745. LocalFree((HLOCAL)pwszFormat);
  1746. if(pInfo)
  1747. free(pInfo);
  1748. return fResult;
  1749. ErrorReturn:
  1750. fResult=FALSE;
  1751. goto CommonReturn;
  1752. SET_ERROR(InvalidArg, E_INVALIDARG);
  1753. TRACE_ERROR(DecodeGenericError);
  1754. TRACE_ERROR(LoadStringError);
  1755. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  1756. TRACE_ERROR(FormatMsgError);
  1757. }
  1758. //--------------------------------------------------------------------------
  1759. //
  1760. // FormatSPCObject:
  1761. //
  1762. // idsPreFix is the pre fix for mulit-line display
  1763. //--------------------------------------------------------------------------
  1764. BOOL FormatSPCObject(
  1765. DWORD dwFormatType,
  1766. DWORD dwFormatStrType,
  1767. void *pFormatStruct,
  1768. UINT idsPreFix,
  1769. PSPC_SERIALIZED_OBJECT pInfo,
  1770. LPWSTR *ppwszFormat)
  1771. {
  1772. BOOL fResult=FALSE;
  1773. LPWSTR pwszHex=NULL;
  1774. LPWSTR pwszClassId=NULL;
  1775. WCHAR wszPreFix[PRE_FIX_SIZE];
  1776. DWORD cbNeeded=0;
  1777. LPWSTR pwszClassFormat=NULL;
  1778. LPWSTR pwszDataFormat=NULL;
  1779. LPWSTR pwszTemp;
  1780. assert(pInfo);
  1781. *ppwszFormat=NULL;
  1782. //load the pre-dix
  1783. if(0!=idsPreFix)
  1784. {
  1785. if(!LoadStringU(hFrmtFuncInst, idsPreFix,
  1786. wszPreFix, sizeof(wszPreFix)/sizeof(wszPreFix[0])))
  1787. goto LoadStringError;
  1788. }
  1789. cbNeeded=0;
  1790. if(!FormatBytesToHex(
  1791. 0,
  1792. dwFormatType,
  1793. dwFormatStrType,
  1794. pFormatStruct,
  1795. NULL,
  1796. pInfo->ClassId,
  1797. 16,
  1798. NULL,
  1799. &cbNeeded))
  1800. goto FormatBytesToHexError;
  1801. pwszClassId=(LPWSTR)malloc(cbNeeded);
  1802. if(NULL==pwszClassId)
  1803. goto MemoryError;
  1804. if(!FormatBytesToHex(
  1805. 0,
  1806. dwFormatType,
  1807. dwFormatStrType,
  1808. pFormatStruct,
  1809. NULL,
  1810. pInfo->ClassId,
  1811. 16,
  1812. pwszClassId,
  1813. &cbNeeded))
  1814. goto FormatBytesToHexError;
  1815. //format
  1816. if(!FormatMessageUnicode(&pwszClassFormat, IDS_SPC_OBJECT_CLASS, pwszClassId))
  1817. goto FormatMsgError;
  1818. //strcat
  1819. *ppwszFormat=(LPWSTR)malloc(sizeof(WCHAR) * (wcslen(pwszClassFormat)+wcslen(wszPreFix)+wcslen(wszCOMMA)+1));
  1820. if(NULL==*ppwszFormat)
  1821. goto MemoryError;
  1822. **ppwszFormat=L'\0';
  1823. if(0!=idsPreFix)
  1824. wcscat(*ppwszFormat, wszPreFix);
  1825. wcscat(*ppwszFormat, pwszClassFormat);
  1826. //format based on the availability of SerializedData
  1827. if(0!=pInfo->SerializedData.cbData)
  1828. {
  1829. //cancatenate the ", " or \n"
  1830. if(NULL != (*ppwszFormat))
  1831. {
  1832. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  1833. wcscat(*ppwszFormat, wszCRLF);
  1834. else
  1835. wcscat(*ppwszFormat, wszCOMMA);
  1836. }
  1837. cbNeeded=0;
  1838. if(!FormatBytesToHex(
  1839. 0,
  1840. dwFormatType,
  1841. dwFormatStrType,
  1842. pFormatStruct,
  1843. NULL,
  1844. pInfo->SerializedData.pbData,
  1845. pInfo->SerializedData.cbData,
  1846. NULL,
  1847. &cbNeeded))
  1848. goto FormatBytesToHexError;
  1849. pwszHex=(LPWSTR)malloc(cbNeeded);
  1850. if(NULL==pwszHex)
  1851. goto MemoryError;
  1852. if(!FormatBytesToHex(
  1853. 0,
  1854. dwFormatType,
  1855. dwFormatStrType,
  1856. pFormatStruct,
  1857. NULL,
  1858. pInfo->SerializedData.pbData,
  1859. pInfo->SerializedData.cbData,
  1860. pwszHex,
  1861. &cbNeeded))
  1862. goto FormatBytesToHexError;
  1863. if(!FormatMessageUnicode(&pwszDataFormat, IDS_SPC_OBJECT_DATA,pwszHex))
  1864. goto FormatMsgError;
  1865. //strcat
  1866. #if (0) // DSIE: Bug 27436
  1867. *ppwszFormat=(LPWSTR)realloc(*ppwszFormat,
  1868. sizeof(WCHAR)* (wcslen(*ppwszFormat)+wcslen(pwszDataFormat)+wcslen(wszPreFix)+1));
  1869. if(NULL==*ppwszFormat)
  1870. goto MemoryError;
  1871. #endif
  1872. pwszTemp=(LPWSTR)realloc(*ppwszFormat,
  1873. sizeof(WCHAR)* (wcslen(*ppwszFormat)+wcslen(pwszDataFormat)+wcslen(wszPreFix)+1));
  1874. if(NULL==pwszTemp)
  1875. goto MemoryError;
  1876. *ppwszFormat = pwszTemp;
  1877. if(0!=idsPreFix)
  1878. wcscat(*ppwszFormat, wszPreFix);
  1879. wcscat(*ppwszFormat, pwszDataFormat);
  1880. }
  1881. fResult=TRUE;
  1882. CommonReturn:
  1883. if(pwszHex)
  1884. free(pwszHex);
  1885. if(pwszClassId)
  1886. free(pwszClassId);
  1887. if(pwszClassFormat)
  1888. LocalFree((HLOCAL)pwszClassFormat);
  1889. if(pwszDataFormat)
  1890. LocalFree((HLOCAL)pwszDataFormat);
  1891. return fResult;
  1892. ErrorReturn:
  1893. if(*ppwszFormat)
  1894. {
  1895. free(*ppwszFormat);
  1896. *ppwszFormat=NULL;
  1897. }
  1898. fResult=FALSE;
  1899. goto CommonReturn;
  1900. TRACE_ERROR(FormatBytesToHexError);
  1901. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  1902. TRACE_ERROR(FormatMsgError);
  1903. TRACE_ERROR(LoadStringError);
  1904. }
  1905. //--------------------------------------------------------------------------
  1906. //
  1907. // FormatSPCLink:
  1908. //--------------------------------------------------------------------------
  1909. BOOL FormatSPCLink(
  1910. DWORD dwFormatType,
  1911. DWORD dwFormatStrType,
  1912. void *pFormatStruct,
  1913. UINT idsPreFix,
  1914. PSPC_LINK pInfo,
  1915. LPWSTR *ppwsz)
  1916. {
  1917. BOOL fResult=FALSE;
  1918. LPWSTR pwszObj=NULL;
  1919. UINT ids=0;
  1920. LPWSTR pwszFormat=NULL;
  1921. assert(pInfo);
  1922. *ppwsz=NULL;
  1923. switch(pInfo->dwLinkChoice)
  1924. {
  1925. case SPC_URL_LINK_CHOICE:
  1926. if(!FormatMessageUnicode(&pwszFormat, IDS_SPC_URL_LINK,pInfo->pwszUrl))
  1927. goto FormatMsgError;
  1928. break;
  1929. case SPC_MONIKER_LINK_CHOICE:
  1930. if(!FormatSPCObject(
  1931. dwFormatType,
  1932. dwFormatStrType,
  1933. pFormatStruct,
  1934. idsPreFix,
  1935. &(pInfo->Moniker),
  1936. &pwszObj))
  1937. goto FormatSPCObjectError;
  1938. //decide between single line and mulitple line format
  1939. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  1940. ids=IDS_SPC_MONIKER_LINK_MULTI;
  1941. else
  1942. ids=IDS_SPC_MONIKER_LINK;
  1943. if(!FormatMessageUnicode(&pwszFormat,ids,pwszObj))
  1944. goto FormatMsgError;
  1945. break;
  1946. case SPC_FILE_LINK_CHOICE:
  1947. if(!FormatMessageUnicode(&pwszFormat, IDS_SPC_FILE_LINK, pInfo->pwszFile))
  1948. goto FormatMsgError;
  1949. break;
  1950. default:
  1951. if(!FormatMessageUnicode(&pwszFormat, IDS_SPC_LINK_UNKNOWN,
  1952. pInfo->dwLinkChoice))
  1953. goto FormatMsgError;
  1954. }
  1955. *ppwsz=(LPWSTR)malloc(sizeof(WCHAR) * (wcslen(pwszFormat)+1));
  1956. if(NULL==(*ppwsz))
  1957. goto MemoryError;
  1958. memcpy(*ppwsz, pwszFormat, sizeof(WCHAR) * (wcslen(pwszFormat)+1));
  1959. fResult=TRUE;
  1960. CommonReturn:
  1961. if(pwszObj)
  1962. free(pwszObj);
  1963. if(pwszFormat)
  1964. LocalFree((HLOCAL)pwszFormat);
  1965. return fResult;
  1966. ErrorReturn:
  1967. if(*ppwsz)
  1968. {
  1969. free(*ppwsz);
  1970. *ppwsz=NULL;
  1971. }
  1972. fResult=FALSE;
  1973. goto CommonReturn;
  1974. TRACE_ERROR(FormatMsgError);
  1975. TRACE_ERROR(FormatSPCObjectError);
  1976. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  1977. }
  1978. //--------------------------------------------------------------------------
  1979. //
  1980. // FormatSPCImage:
  1981. //--------------------------------------------------------------------------
  1982. BOOL FormatSPCImage(
  1983. DWORD dwFormatType,
  1984. DWORD dwFormatStrType,
  1985. void *pFormatStruct,
  1986. UINT idsPreFix,
  1987. PSPC_IMAGE pInfo,
  1988. LPWSTR *ppwszImageFormat)
  1989. {
  1990. BOOL fResult=FALSE;
  1991. LPWSTR pwszFormat=NULL;
  1992. LPWSTR pwszLink=NULL;
  1993. LPWSTR pwszLinkFormat=NULL;
  1994. LPWSTR pwszHex=NULL;
  1995. LPWSTR pwszHexFormat=NULL;
  1996. UINT ids=0;
  1997. DWORD cbNeeded=0;
  1998. LPWSTR pwszTemp;
  1999. assert(pInfo);
  2000. //init
  2001. *ppwszImageFormat=NULL;
  2002. pwszFormat=(LPWSTR)malloc(sizeof(WCHAR));
  2003. if(NULL==pwszFormat)
  2004. goto MemoryError;
  2005. *pwszFormat=L'\0';
  2006. if(pInfo->pImageLink)
  2007. {
  2008. if(!FormatSPCLink(dwFormatType,
  2009. dwFormatStrType,
  2010. pFormatStruct,
  2011. idsPreFix,
  2012. pInfo->pImageLink,
  2013. &pwszLink))
  2014. goto FormatSPCLinkError;
  2015. //decide between single line and mulitple line format
  2016. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  2017. ids=IDS_IMAGE_LINK_MULTI;
  2018. else
  2019. ids=IDS_IMAGE_LINK;
  2020. if(!FormatMessageUnicode(&pwszLinkFormat, ids,
  2021. &pwszLink))
  2022. goto FormatMsgError;
  2023. #if (0) // DSIE: Bug 27436
  2024. pwszFormat=(LPWSTR)realloc(pwszFormat,
  2025. sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszCOMMA)+wcslen(pwszLinkFormat)+1));
  2026. if(NULL==pwszFormat)
  2027. goto MemoryError;
  2028. #endif
  2029. pwszTemp=(LPWSTR)realloc(pwszFormat,
  2030. sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszCOMMA)+wcslen(pwszLinkFormat)+1));
  2031. if(NULL==pwszTemp)
  2032. goto MemoryError;
  2033. pwszFormat = pwszTemp;
  2034. wcscat(pwszFormat, pwszLinkFormat);
  2035. }
  2036. if(0!=pInfo->Bitmap.cbData)
  2037. {
  2038. //strcat ", "
  2039. if(0!=wcslen(pwszFormat))
  2040. {
  2041. if(0== (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
  2042. wcscat(pwszFormat, wszCOMMA);
  2043. }
  2044. cbNeeded=0;
  2045. if(!FormatBytesToHex(
  2046. 0,
  2047. dwFormatType,
  2048. dwFormatStrType,
  2049. pFormatStruct,
  2050. NULL,
  2051. pInfo->Bitmap.pbData,
  2052. pInfo->Bitmap.cbData,
  2053. NULL,
  2054. &cbNeeded))
  2055. goto FormatBytesToHexError;
  2056. pwszHex=(LPWSTR)malloc(cbNeeded);
  2057. if(NULL==pwszHex)
  2058. goto MemoryError;
  2059. if(!FormatBytesToHex(
  2060. 0,
  2061. dwFormatType,
  2062. dwFormatStrType,
  2063. pFormatStruct,
  2064. NULL,
  2065. pInfo->Bitmap.pbData,
  2066. pInfo->Bitmap.cbData,
  2067. pwszHex,
  2068. &cbNeeded))
  2069. goto FormatBytesToHexError;
  2070. //decide between single line and mulitple line format
  2071. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  2072. ids=IDS_IMAGE_BITMAP_MULTI;
  2073. else
  2074. ids=IDS_IMAGE_BITMAP;
  2075. if(!FormatMessageUnicode(&pwszHexFormat, ids, pwszHex))
  2076. goto FormatMsgError;
  2077. #if (0) // DSIE: Bug 27436
  2078. pwszFormat=(LPWSTR)realloc(pwszFormat,
  2079. sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszCOMMA)+wcslen(pwszHexFormat)+1));
  2080. if(NULL==pwszFormat)
  2081. goto MemoryError;
  2082. #endif
  2083. pwszTemp=(LPWSTR)realloc(pwszFormat,
  2084. sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszCOMMA)+wcslen(pwszHexFormat)+1));
  2085. if(NULL==pwszTemp)
  2086. goto MemoryError;
  2087. pwszFormat = pwszTemp;
  2088. wcscat(pwszFormat, pwszHexFormat);
  2089. //free memory
  2090. free(pwszHex);
  2091. pwszHex=NULL;
  2092. LocalFree((HLOCAL)pwszHexFormat);
  2093. pwszHexFormat=NULL;
  2094. }
  2095. if(0!=pInfo->Metafile.cbData)
  2096. {
  2097. //strcat ", "
  2098. if(0!=wcslen(pwszFormat))
  2099. {
  2100. if(0== (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
  2101. wcscat(pwszFormat, wszCOMMA);
  2102. }
  2103. cbNeeded=0;
  2104. if(!FormatBytesToHex(
  2105. 0,
  2106. dwFormatType,
  2107. dwFormatStrType,
  2108. pFormatStruct,
  2109. NULL,
  2110. pInfo->Metafile.pbData,
  2111. pInfo->Metafile.cbData,
  2112. NULL,
  2113. &cbNeeded))
  2114. goto FormatBytesToHexError;
  2115. pwszHex=(LPWSTR)malloc(cbNeeded);
  2116. if(NULL==pwszHex)
  2117. goto MemoryError;
  2118. if(!FormatBytesToHex(
  2119. 0,
  2120. dwFormatType,
  2121. dwFormatStrType,
  2122. pFormatStruct,
  2123. NULL,
  2124. pInfo->Metafile.pbData,
  2125. pInfo->Metafile.cbData,
  2126. pwszHex,
  2127. &cbNeeded))
  2128. goto FormatBytesToHexError;
  2129. //decide between single line and mulitple line format
  2130. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  2131. ids=IDS_IMAGE_METAFILE_MULTI;
  2132. else
  2133. ids=IDS_IMAGE_METAFILE;
  2134. if(!FormatMessageUnicode(&pwszHexFormat, ids, pwszHex))
  2135. goto FormatMsgError;
  2136. #if (0) // DSIE: Bug 27436
  2137. pwszFormat=(LPWSTR)realloc(pwszFormat,
  2138. sizeof(WCHAR) *(wcslen(pwszFormat)+wcslen(wszCOMMA)+wcslen(pwszHexFormat)+1));
  2139. if(NULL==pwszFormat)
  2140. goto MemoryError;
  2141. #endif
  2142. pwszTemp=(LPWSTR)realloc(pwszFormat,
  2143. sizeof(WCHAR) *(wcslen(pwszFormat)+wcslen(wszCOMMA)+wcslen(pwszHexFormat)+1));
  2144. if(NULL==pwszTemp)
  2145. goto MemoryError;
  2146. pwszFormat = pwszTemp;
  2147. wcscat(pwszFormat, pwszHexFormat);
  2148. //free memory
  2149. free(pwszHex);
  2150. pwszHex=NULL;
  2151. LocalFree((HLOCAL)pwszHexFormat);
  2152. pwszHexFormat=NULL;
  2153. }
  2154. if(0!=pInfo->EnhancedMetafile.cbData)
  2155. {
  2156. //strcat ", "
  2157. if(0!=wcslen(pwszFormat))
  2158. {
  2159. if(0== (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
  2160. wcscat(pwszFormat, wszCOMMA);
  2161. }
  2162. cbNeeded=0;
  2163. if(!FormatBytesToHex(
  2164. 0,
  2165. dwFormatType,
  2166. dwFormatStrType,
  2167. pFormatStruct,
  2168. NULL,
  2169. pInfo->EnhancedMetafile.pbData,
  2170. pInfo->EnhancedMetafile.cbData,
  2171. NULL,
  2172. &cbNeeded))
  2173. goto FormatBytesToHexError;
  2174. pwszHex=(LPWSTR)malloc(cbNeeded);
  2175. if(NULL==pwszHex)
  2176. goto MemoryError;
  2177. if(!FormatBytesToHex(
  2178. 0,
  2179. dwFormatType,
  2180. dwFormatStrType,
  2181. pFormatStruct,
  2182. NULL,
  2183. pInfo->EnhancedMetafile.pbData,
  2184. pInfo->EnhancedMetafile.cbData,
  2185. pwszHex,
  2186. &cbNeeded))
  2187. goto FormatBytesToHexError;
  2188. //decide between single line and mulitple line format
  2189. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  2190. ids=IDS_IMAGE_ENHANCED_METAFILE_MULTI;
  2191. else
  2192. ids=IDS_IMAGE_ENHANCED_METAFILE;
  2193. if(!FormatMessageUnicode(&pwszHexFormat, ids, pwszHex))
  2194. goto FormatMsgError;
  2195. #if (0) // DSIE: Bug 27436
  2196. pwszFormat=(LPWSTR)realloc(pwszFormat,
  2197. sizeof(WCHAR) *(wcslen(pwszFormat)+wcslen(wszCOMMA)+wcslen(pwszHexFormat)+1));
  2198. if(NULL==pwszFormat)
  2199. goto MemoryError;
  2200. #endif
  2201. pwszTemp=(LPWSTR)realloc(pwszFormat,
  2202. sizeof(WCHAR) *(wcslen(pwszFormat)+wcslen(wszCOMMA)+wcslen(pwszHexFormat)+1));
  2203. if(NULL==pwszTemp)
  2204. goto MemoryError;
  2205. pwszFormat = pwszTemp;
  2206. wcscat(pwszFormat, pwszHexFormat);
  2207. //free memory
  2208. free(pwszHex);
  2209. pwszHex=NULL;
  2210. LocalFree((HLOCAL)pwszHexFormat);
  2211. pwszHexFormat=NULL;
  2212. }
  2213. if(0!=pInfo->GifFile.cbData)
  2214. {
  2215. //strcat ", "
  2216. if(0!=wcslen(pwszFormat))
  2217. {
  2218. if(0== (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
  2219. wcscat(pwszFormat, wszCOMMA);
  2220. }
  2221. cbNeeded=0;
  2222. if(!FormatBytesToHex(
  2223. 0,
  2224. dwFormatType,
  2225. dwFormatStrType,
  2226. pFormatStruct,
  2227. NULL,
  2228. pInfo->GifFile.pbData,
  2229. pInfo->GifFile.cbData,
  2230. NULL,
  2231. &cbNeeded))
  2232. goto FormatBytesToHexError;
  2233. pwszHex=(LPWSTR)malloc(cbNeeded);
  2234. if(NULL==pwszHex)
  2235. goto MemoryError;
  2236. if(!FormatBytesToHex(
  2237. 0,
  2238. dwFormatType,
  2239. dwFormatStrType,
  2240. pFormatStruct,
  2241. NULL,
  2242. pInfo->GifFile.pbData,
  2243. pInfo->GifFile.cbData,
  2244. pwszHex,
  2245. &cbNeeded))
  2246. goto FormatBytesToHexError;
  2247. //decide between single line and mulitple line format
  2248. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  2249. ids=IDS_IMAGE_GIFFILE_MULTI;
  2250. else
  2251. ids=IDS_IMAGE_GIFFILE;
  2252. if(!FormatMessageUnicode(&pwszHexFormat, IDS_IMAGE_GIFFILE,
  2253. pwszHex))
  2254. goto FormatMsgError;
  2255. #if (0) // DSIE: Bug 27436
  2256. pwszFormat=(LPWSTR)realloc(pwszFormat,
  2257. sizeof(WCHAR) *(wcslen(pwszFormat)+wcslen(wszCOMMA)+wcslen(pwszHexFormat)+1));
  2258. if(NULL==pwszFormat)
  2259. goto MemoryError;
  2260. #endif
  2261. pwszTemp=(LPWSTR)realloc(pwszFormat,
  2262. sizeof(WCHAR) *(wcslen(pwszFormat)+wcslen(wszCOMMA)+wcslen(pwszHexFormat)+1));
  2263. if(NULL==pwszTemp)
  2264. goto MemoryError;
  2265. pwszFormat = pwszTemp;
  2266. wcscat(pwszFormat, pwszHexFormat);
  2267. //free memory
  2268. free(pwszHex);
  2269. pwszHex=NULL;
  2270. LocalFree((HLOCAL)pwszHexFormat);
  2271. pwszHexFormat=NULL;
  2272. }
  2273. if(0==wcslen(pwszFormat))
  2274. {
  2275. //fine if nothing is formatted
  2276. *ppwszImageFormat=NULL;
  2277. }
  2278. else
  2279. {
  2280. *ppwszImageFormat=(LPWSTR)malloc(sizeof(WCHAR)*(wcslen(pwszFormat)+1));
  2281. #if (0) // DSIE: Bug 27432 & 27434
  2282. if(NULL == ppwszImageFormat)
  2283. #endif
  2284. if(NULL == *ppwszImageFormat)
  2285. goto MemoryError;
  2286. memcpy(*ppwszImageFormat, pwszFormat, sizeof(WCHAR)*(wcslen(pwszFormat)+1));
  2287. }
  2288. fResult=TRUE;
  2289. CommonReturn:
  2290. if(pwszHex)
  2291. free(pwszHex);
  2292. if(pwszHexFormat)
  2293. LocalFree((HLOCAL)pwszHexFormat);
  2294. if(pwszLink)
  2295. free(pwszLink);
  2296. if(pwszLinkFormat)
  2297. LocalFree((HLOCAL)pwszLinkFormat);
  2298. if(pwszFormat)
  2299. free(pwszFormat);
  2300. return fResult;
  2301. ErrorReturn:
  2302. if(*ppwszImageFormat)
  2303. {
  2304. free(*ppwszImageFormat);
  2305. *ppwszImageFormat=NULL;
  2306. }
  2307. fResult=FALSE;
  2308. goto CommonReturn;
  2309. TRACE_ERROR(FormatSPCLinkError);
  2310. TRACE_ERROR(FormatMsgError);
  2311. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  2312. TRACE_ERROR(FormatBytesToHexError);
  2313. }
  2314. //--------------------------------------------------------------------------
  2315. //
  2316. // FormatSPAgencyInfo: SPC_SP_AGENCY_INFO_STRUCT
  2317. // SPC_SP_AGENCY_INFO_OBJID
  2318. //--------------------------------------------------------------------------
  2319. static BOOL
  2320. WINAPI
  2321. FormatSPAgencyInfo(
  2322. DWORD dwCertEncodingType,
  2323. DWORD dwFormatType,
  2324. DWORD dwFormatStrType,
  2325. void *pFormatStruct,
  2326. LPCSTR lpszStructType,
  2327. const BYTE *pbEncoded,
  2328. DWORD cbEncoded,
  2329. void *pbFormat,
  2330. DWORD *pcbFormat)
  2331. {
  2332. LPWSTR pwszFormat=NULL;
  2333. LPWSTR pwsz=NULL;
  2334. PSPC_SP_AGENCY_INFO pInfo=NULL;
  2335. LPWSTR pwszPolicyInfo=NULL;
  2336. LPWSTR pwszPolicyInfoFormat=NULL;
  2337. LPWSTR pwszLogoLink=NULL;
  2338. LPWSTR pwszLogoLinkFormat=NULL;
  2339. LPWSTR pwszPolicyDsplyFormat=NULL;
  2340. LPWSTR pwszLogoImage=NULL;
  2341. LPWSTR pwszLogoImageFormat=NULL;
  2342. DWORD cbNeeded=0;
  2343. BOOL fResult=FALSE;
  2344. UINT ids=0;
  2345. LPWSTR pwszTemp;
  2346. //check for input parameters
  2347. if((NULL==pbEncoded&& cbEncoded!=0) ||
  2348. (NULL==pcbFormat))
  2349. goto InvalidArg;
  2350. if(cbEncoded==0)
  2351. {
  2352. *pcbFormat=0;
  2353. goto InvalidArg;
  2354. }
  2355. if (!DecodeGenericBLOB(dwCertEncodingType,SPC_SP_AGENCY_INFO_STRUCT,
  2356. pbEncoded,cbEncoded, (void **)&pInfo))
  2357. goto DecodeGenericError;
  2358. pwsz=(LPWSTR)malloc(sizeof(WCHAR));
  2359. if(NULL==pwsz)
  2360. goto MemoryError;
  2361. *pwsz=L'\0';
  2362. //format pPolicyInformation
  2363. if(pInfo->pPolicyInformation)
  2364. {
  2365. //decide between single line and mulitple line format
  2366. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  2367. ids=IDS_TWO_TABS;
  2368. else
  2369. ids=0;
  2370. if(!FormatSPCLink(dwFormatType,
  2371. dwFormatStrType,
  2372. pFormatStruct,
  2373. ids,
  2374. pInfo->pPolicyInformation,
  2375. &pwszPolicyInfo))
  2376. goto FormatSPCLinkError;
  2377. //decide between single line and mulitple line format
  2378. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  2379. ids=IDS_AGENCY_POLICY_INFO_MULTI;
  2380. else
  2381. ids=IDS_AGENCY_POLICY_INFO;
  2382. if(!FormatMessageUnicode(&pwszPolicyInfoFormat, ids, pwszPolicyInfo))
  2383. goto FormatMsgError;
  2384. //strcat
  2385. #if (0) // DSIE: Bug 27436
  2386. pwsz=(LPWSTR)realloc(pwsz,
  2387. sizeof(WCHAR) *(wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszPolicyInfoFormat)+1));
  2388. if(NULL==pwsz)
  2389. goto MemoryError;
  2390. #endif
  2391. pwszTemp=(LPWSTR)realloc(pwsz,
  2392. sizeof(WCHAR) *(wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszPolicyInfoFormat)+1));
  2393. if(NULL==pwszTemp)
  2394. goto MemoryError;
  2395. pwsz = pwszTemp;
  2396. wcscat(pwsz, pwszPolicyInfoFormat);
  2397. }
  2398. //format pwszPolicyDisplayText
  2399. if(pInfo->pwszPolicyDisplayText)
  2400. {
  2401. //strcat ", "
  2402. if(0!=wcslen(pwsz))
  2403. {
  2404. if(0== (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
  2405. wcscat(pwsz, wszCOMMA);
  2406. }
  2407. //decide between single line and mulitple line format
  2408. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  2409. ids=IDS_AGENCY_POLICY_DSPLY_MULTI;
  2410. else
  2411. ids=IDS_AGENCY_POLICY_DSPLY;
  2412. if(!FormatMessageUnicode(&pwszPolicyDsplyFormat, ids, pInfo->pwszPolicyDisplayText))
  2413. goto FormatMsgError;
  2414. //strcat
  2415. #if (0) // DSIE: Bug 27436
  2416. pwsz=(LPWSTR)realloc(pwsz,
  2417. sizeof(WCHAR) *(wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszPolicyDsplyFormat)+1));
  2418. if(NULL==pwsz)
  2419. goto MemoryError;
  2420. #endif
  2421. pwszTemp=(LPWSTR)realloc(pwsz,
  2422. sizeof(WCHAR) *(wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszPolicyDsplyFormat)+1));
  2423. if(NULL==pwszTemp)
  2424. goto MemoryError;
  2425. pwsz = pwszTemp;
  2426. wcscat(pwsz, pwszPolicyDsplyFormat);
  2427. }
  2428. //pLogoImage
  2429. if(pInfo->pLogoImage)
  2430. {
  2431. //decide between single line and mulitple line format
  2432. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  2433. ids=IDS_THREE_TABS;
  2434. else
  2435. ids=0;
  2436. if(!FormatSPCImage(dwFormatType,
  2437. dwFormatStrType,
  2438. pFormatStruct,
  2439. ids,
  2440. pInfo->pLogoImage,
  2441. &pwszLogoImage))
  2442. goto FormatSPCImageError;
  2443. //spcImage can include nothing
  2444. if(NULL!=pwszLogoImage)
  2445. {
  2446. //strcat ", "
  2447. if(0!=wcslen(pwsz))
  2448. {
  2449. if(0== (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
  2450. wcscat(pwsz, wszCOMMA);
  2451. }
  2452. //decide between single line and mulitple line format
  2453. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  2454. ids=IDS_AGENCY_LOGO_IMAGE_MULTI;
  2455. else
  2456. ids=IDS_AGENCY_LOGO_IMAGE;
  2457. if(!FormatMessageUnicode(&pwszLogoImageFormat,ids,pwszLogoImage))
  2458. goto FormatMsgError;
  2459. //strcat
  2460. #if (0) // DSIE: Bug 27436
  2461. pwsz=(LPWSTR)realloc(pwsz,
  2462. sizeof(WCHAR) *(wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszLogoImageFormat)+1));
  2463. if(NULL==pwsz)
  2464. goto MemoryError;
  2465. #endif
  2466. pwszTemp=(LPWSTR)realloc(pwsz,
  2467. sizeof(WCHAR) *(wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszLogoImageFormat)+1));
  2468. if(NULL==pwszTemp)
  2469. goto MemoryError;
  2470. pwsz = pwszTemp;
  2471. wcscat(pwsz, pwszLogoImageFormat);
  2472. }
  2473. }
  2474. //format pLogoLink
  2475. if(pInfo->pLogoLink)
  2476. {
  2477. //strcat ", "
  2478. if(0!=wcslen(pwsz))
  2479. {
  2480. if(0== (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
  2481. wcscat(pwsz, wszCOMMA);
  2482. }
  2483. //decide between single line and mulitple line format
  2484. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  2485. ids=IDS_TWO_TABS;
  2486. else
  2487. ids=0;
  2488. if(!FormatSPCLink(dwFormatType,
  2489. dwFormatStrType,
  2490. pFormatStruct,
  2491. ids,
  2492. pInfo->pLogoLink,
  2493. &pwszLogoLink))
  2494. goto FormatSPCLinkError;
  2495. //decide between single line and mulitple line format
  2496. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  2497. ids=IDS_AGENCY_LOGO_LINK_MULTI;
  2498. else
  2499. ids=IDS_AGENCY_LOGO_LINK;
  2500. if(!FormatMessageUnicode(&pwszLogoLinkFormat, ids, pwszLogoLink))
  2501. goto FormatMsgError;
  2502. //strcat
  2503. #if (0) // DSIE: Bug 27436
  2504. pwsz=(LPWSTR)realloc(pwsz,
  2505. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszLogoLinkFormat)+1));
  2506. if(NULL==pwsz)
  2507. goto MemoryError;
  2508. #endif
  2509. pwszTemp=(LPWSTR)realloc(pwsz,
  2510. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszLogoLinkFormat)+1));
  2511. if(NULL==pwszTemp)
  2512. goto MemoryError;
  2513. pwsz = pwszTemp;
  2514. wcscat(pwsz, pwszLogoLinkFormat);
  2515. }
  2516. if(0==wcslen(pwsz))
  2517. {
  2518. //no data
  2519. pwszFormat=(LPWSTR)malloc((NO_INFO_SIZE+1)*sizeof(WCHAR));
  2520. if(NULL==pwszFormat)
  2521. goto MemoryError;
  2522. if(!LoadStringU(hFrmtFuncInst,IDS_NO_INFO, pwszFormat, NO_INFO_SIZE))
  2523. goto LoadStringError;
  2524. }
  2525. else
  2526. {
  2527. pwszFormat=pwsz;
  2528. pwsz=NULL;
  2529. }
  2530. cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
  2531. //length only calculation
  2532. if(NULL==pbFormat)
  2533. {
  2534. *pcbFormat=cbNeeded;
  2535. fResult=TRUE;
  2536. goto CommonReturn;
  2537. }
  2538. if((*pcbFormat)<cbNeeded)
  2539. {
  2540. *pcbFormat=cbNeeded;
  2541. goto MoreDataError;
  2542. }
  2543. //copy the data
  2544. memcpy(pbFormat, pwszFormat, cbNeeded);
  2545. //copy the size
  2546. *pcbFormat=cbNeeded;
  2547. fResult=TRUE;
  2548. CommonReturn:
  2549. if(pwszPolicyInfo)
  2550. free(pwszPolicyInfo);
  2551. if(pwszPolicyInfoFormat)
  2552. LocalFree((HLOCAL)pwszPolicyInfoFormat);
  2553. if(pwszLogoLink)
  2554. free(pwszLogoLink);
  2555. if(pwszLogoLinkFormat)
  2556. LocalFree((HLOCAL)pwszLogoLinkFormat);
  2557. if(pwszPolicyDsplyFormat)
  2558. LocalFree((HLOCAL)pwszPolicyDsplyFormat);
  2559. if(pwszLogoImage)
  2560. free(pwszLogoImage);
  2561. if(pwszLogoImageFormat)
  2562. LocalFree((HLOCAL)pwszLogoImageFormat);
  2563. if(pwszFormat)
  2564. free(pwszFormat);
  2565. if(pwsz)
  2566. free(pwsz);
  2567. if(pInfo)
  2568. free(pInfo);
  2569. return fResult;
  2570. ErrorReturn:
  2571. fResult=FALSE;
  2572. goto CommonReturn;
  2573. SET_ERROR(InvalidArg, E_INVALIDARG);
  2574. TRACE_ERROR(DecodeGenericError);
  2575. TRACE_ERROR(LoadStringError);
  2576. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  2577. TRACE_ERROR(FormatMsgError);
  2578. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  2579. TRACE_ERROR(FormatSPCLinkError);
  2580. TRACE_ERROR(FormatSPCImageError);
  2581. }
  2582. //--------------------------------------------------------------------------
  2583. //
  2584. // GetNoticeNumberString:
  2585. //
  2586. // The memory should be allocated via malloc
  2587. //--------------------------------------------------------------------------
  2588. BOOL WINAPI GetNoticeNumberString( DWORD cNoticeNumbers,
  2589. int *rgNoticeNumbers,
  2590. LPWSTR *ppwszNumber)
  2591. {
  2592. BOOL fResult=FALSE;
  2593. WCHAR wszNumber[INT_SIZE];
  2594. DWORD dwIndex=0;
  2595. LPWSTR pwszTemp;
  2596. *ppwszNumber=NULL;
  2597. if(NULL==rgNoticeNumbers || 0==cNoticeNumbers)
  2598. goto InvalidArg;
  2599. *ppwszNumber=(LPWSTR)malloc(sizeof(WCHAR));
  2600. if(NULL==*ppwszNumber)
  2601. goto MemoryError;
  2602. **ppwszNumber=L'\0';
  2603. for(dwIndex=0; dwIndex<cNoticeNumbers; dwIndex++)
  2604. {
  2605. wszNumber[0]='\0';
  2606. _itow(rgNoticeNumbers[dwIndex], wszNumber, 10);
  2607. if(wcslen(wszNumber) > 0)
  2608. {
  2609. #if (0) // DSIE: Bug 27436
  2610. *ppwszNumber=(LPWSTR)realloc(*ppwszNumber,
  2611. sizeof(WCHAR)*(wcslen(*ppwszNumber)+wcslen(wszNumber)+wcslen(wszCOMMA)+1));
  2612. if(NULL==*ppwszNumber)
  2613. goto MemoryError;
  2614. #endif
  2615. pwszTemp=(LPWSTR)realloc(*ppwszNumber,
  2616. sizeof(WCHAR)*(wcslen(*ppwszNumber)+wcslen(wszNumber)+wcslen(wszCOMMA)+1));
  2617. if(NULL==pwszTemp)
  2618. goto MemoryError;
  2619. *ppwszNumber = pwszTemp;
  2620. wcscat(*ppwszNumber, wszNumber);
  2621. if(dwIndex != (cNoticeNumbers-1))
  2622. wcscat(*ppwszNumber, wszCOMMA);
  2623. }
  2624. }
  2625. if(0==wcslen(*ppwszNumber))
  2626. goto InvalidArg;
  2627. fResult=TRUE;
  2628. CommonReturn:
  2629. return fResult;
  2630. ErrorReturn:
  2631. if(*ppwszNumber)
  2632. {
  2633. free(*ppwszNumber);
  2634. *ppwszNumber=NULL;
  2635. }
  2636. fResult=FALSE;
  2637. goto CommonReturn;
  2638. SET_ERROR(InvalidArg, E_INVALIDARG);
  2639. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  2640. }
  2641. //--------------------------------------------------------------------------
  2642. //
  2643. // FormatCertQualifier:
  2644. //
  2645. // The memory should be allocated via malloc
  2646. //--------------------------------------------------------------------------
  2647. BOOL FormatPolicyUserNotice(
  2648. DWORD dwCertEncodingType,
  2649. DWORD dwFormatType,
  2650. DWORD dwFormatStrType,
  2651. void *pFormatStruct,
  2652. UINT idsPreFix,
  2653. BYTE *pbEncoded,
  2654. DWORD cbEncoded,
  2655. LPWSTR *ppwsz)
  2656. {
  2657. BOOL fResult=FALSE;
  2658. WCHAR wszNoInfo[NO_INFO_SIZE];
  2659. WCHAR wszPreFix[PREFIX_SIZE];
  2660. WCHAR wszNextPre[PREFIX_SIZE];
  2661. WCHAR wszText[SUBJECT_SIZE];
  2662. BOOL fComma=FALSE;
  2663. CERT_POLICY_QUALIFIER_USER_NOTICE *pInfo=NULL;
  2664. LPWSTR pwszOrg=NULL;
  2665. LPWSTR pwszNumber=NULL;
  2666. LPWSTR pwszTemp;
  2667. *ppwsz=NULL;
  2668. if (!DecodeGenericBLOB(dwCertEncodingType, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE,
  2669. pbEncoded,cbEncoded, (void **)&pInfo))
  2670. goto DecodeGenericError;
  2671. if(!LoadStringU(hFrmtFuncInst,idsPreFix, wszPreFix, sizeof(wszPreFix)/sizeof(wszPreFix[0])))
  2672. goto LoadStringError;
  2673. if(!LoadStringU(hFrmtFuncInst,idsPreFix+1, wszNextPre, sizeof(wszNextPre)/sizeof(wszNextPre[0])))
  2674. goto LoadStringError;
  2675. if(NULL == pInfo->pNoticeReference && NULL == pInfo->pszDisplayText)
  2676. {
  2677. //load the string "Info Not Available"
  2678. if(!LoadStringU(hFrmtFuncInst,IDS_NO_INFO, wszNoInfo, sizeof(wszNoInfo)/sizeof(wszNoInfo[0])))
  2679. goto LoadStringError;
  2680. *ppwsz=(LPWSTR)malloc(sizeof(WCHAR) * (wcslen(wszNoInfo) + wcslen(wszPreFix) + POSTFIX_SIZE + 1));
  2681. if(NULL==*ppwsz)
  2682. goto MemoryError;
  2683. **ppwsz=L'\0';
  2684. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  2685. wcscat(*ppwsz, wszPreFix);
  2686. wcscat(*ppwsz, wszNoInfo);
  2687. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  2688. wcscat(*ppwsz, wszCRLF);
  2689. }
  2690. else
  2691. {
  2692. *ppwsz=(LPWSTR)malloc(sizeof(WCHAR));
  2693. if(NULL==*ppwsz)
  2694. goto MemoryError;
  2695. **ppwsz=L'\0';
  2696. if(pInfo->pNoticeReference)
  2697. {
  2698. if(!LoadStringU(hFrmtFuncInst,IDS_USER_NOTICE_REF, wszText, sizeof(wszText)/sizeof(wszText[0])))
  2699. goto LoadStringError;
  2700. #if (0) // DSIE: Bug 27436
  2701. *ppwsz=(LPWSTR)realloc(*ppwsz,
  2702. sizeof(WCHAR) * (wcslen(*ppwsz)+wcslen(wszText)+wcslen(wszPreFix)+POSTFIX_SIZE+1));
  2703. if(NULL==*ppwsz)
  2704. goto MemoryError;
  2705. #endif
  2706. pwszTemp=(LPWSTR)realloc(*ppwsz,
  2707. sizeof(WCHAR) * (wcslen(*ppwsz)+wcslen(wszText)+wcslen(wszPreFix)+POSTFIX_SIZE+1));
  2708. if(NULL==pwszTemp)
  2709. goto MemoryError;
  2710. *ppwsz = pwszTemp;
  2711. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  2712. wcscat(*ppwsz, wszPreFix);
  2713. wcscat(*ppwsz, wszText);
  2714. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  2715. wcscat(*ppwsz, wszCRLF);
  2716. if(pInfo->pNoticeReference->pszOrganization)
  2717. {
  2718. if(S_OK!=SZtoWSZ(pInfo->pNoticeReference->pszOrganization, &pwszOrg))
  2719. goto SZtoWSZError;
  2720. if(!LoadStringU(hFrmtFuncInst,IDS_USER_NOTICE_REF_ORG, wszText, sizeof(wszText)/sizeof(wszText[0])))
  2721. goto LoadStringError;
  2722. #if (0) // DSIE: Bug 27436
  2723. *ppwsz=(LPWSTR)realloc(*ppwsz,
  2724. sizeof(WCHAR) * (wcslen(*ppwsz)+wcslen(wszText)+wcslen(pwszOrg)+wcslen(wszNextPre)+POSTFIX_SIZE+1));
  2725. if(NULL==*ppwsz)
  2726. goto MemoryError;
  2727. #endif
  2728. pwszTemp=(LPWSTR)realloc(*ppwsz,
  2729. sizeof(WCHAR) * (wcslen(*ppwsz)+wcslen(wszText)+wcslen(pwszOrg)+wcslen(wszNextPre)+POSTFIX_SIZE+1));
  2730. if(NULL==pwszTemp)
  2731. goto MemoryError;
  2732. *ppwsz = pwszTemp;
  2733. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  2734. wcscat(*ppwsz, wszNextPre);
  2735. wcscat(*ppwsz, wszText);
  2736. wcscat(*ppwsz, pwszOrg);
  2737. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  2738. wcscat(*ppwsz, wszCRLF);
  2739. else
  2740. {
  2741. wcscat(*ppwsz, wszCOMMA);
  2742. fComma=TRUE;
  2743. }
  2744. }
  2745. if(pInfo->pNoticeReference->cNoticeNumbers)
  2746. {
  2747. if(NULL == pInfo->pNoticeReference->rgNoticeNumbers)
  2748. goto InvalidArg;
  2749. if(!GetNoticeNumberString(pInfo->pNoticeReference->cNoticeNumbers,
  2750. pInfo->pNoticeReference->rgNoticeNumbers,
  2751. &pwszNumber))
  2752. goto GetNumberError;
  2753. if(!LoadStringU(hFrmtFuncInst,IDS_USER_NOTICE_REF_NUMBER, wszText, sizeof(wszText)/sizeof(wszText[0])))
  2754. goto LoadStringError;
  2755. #if (0) // DSIE: Bug 27436
  2756. *ppwsz=(LPWSTR)realloc(*ppwsz,
  2757. sizeof(WCHAR) * (wcslen(*ppwsz)+wcslen(wszText)+wcslen(pwszNumber)+wcslen(wszNextPre)+POSTFIX_SIZE+1));
  2758. if(NULL==*ppwsz)
  2759. goto MemoryError;
  2760. #endif
  2761. pwszTemp=(LPWSTR)realloc(*ppwsz,
  2762. sizeof(WCHAR) * (wcslen(*ppwsz)+wcslen(wszText)+wcslen(pwszNumber)+wcslen(wszNextPre)+POSTFIX_SIZE+1));
  2763. if(NULL==pwszTemp)
  2764. goto MemoryError;
  2765. *ppwsz = pwszTemp;
  2766. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  2767. wcscat(*ppwsz, wszNextPre);
  2768. wcscat(*ppwsz, wszText);
  2769. wcscat(*ppwsz, pwszNumber);
  2770. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  2771. wcscat(*ppwsz, wszCRLF);
  2772. else
  2773. {
  2774. wcscat(*ppwsz, wszCOMMA);
  2775. fComma=TRUE;
  2776. }
  2777. }
  2778. }
  2779. if(pInfo->pszDisplayText)
  2780. {
  2781. if(!LoadStringU(hFrmtFuncInst,IDS_USER_NOTICE_TEXT, wszText, sizeof(wszText)/sizeof(wszText[0])))
  2782. goto LoadStringError;
  2783. #if (0) // DSIE: Bug 27436
  2784. *ppwsz=(LPWSTR)realloc(*ppwsz,
  2785. sizeof(WCHAR) * (wcslen(*ppwsz)+wcslen(wszText)+wcslen(pInfo->pszDisplayText)+wcslen(wszPreFix)+POSTFIX_SIZE+1));
  2786. if(NULL==*ppwsz)
  2787. goto MemoryError;
  2788. #endif
  2789. pwszTemp=(LPWSTR)realloc(*ppwsz,
  2790. sizeof(WCHAR) * (wcslen(*ppwsz)+wcslen(wszText)+wcslen(pInfo->pszDisplayText)+wcslen(wszPreFix)+POSTFIX_SIZE+1));
  2791. if(NULL==pwszTemp)
  2792. goto MemoryError;
  2793. *ppwsz = pwszTemp;
  2794. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  2795. wcscat(*ppwsz, wszPreFix);
  2796. wcscat(*ppwsz, wszText);
  2797. wcscat(*ppwsz, pInfo->pszDisplayText);
  2798. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  2799. wcscat(*ppwsz, wszCRLF);
  2800. else
  2801. {
  2802. wcscat(*ppwsz, wszCOMMA);
  2803. fComma=TRUE;
  2804. }
  2805. }
  2806. //get rid of the last comma
  2807. if(fComma)
  2808. *(*ppwsz+wcslen(*ppwsz)-wcslen(wszCOMMA))=L'\0';
  2809. }
  2810. fResult=TRUE;
  2811. CommonReturn:
  2812. if(pInfo)
  2813. free(pInfo);
  2814. if(pwszOrg)
  2815. free(pwszOrg);
  2816. if(pwszNumber)
  2817. free(pwszNumber);
  2818. return fResult;
  2819. ErrorReturn:
  2820. if(*ppwsz)
  2821. {
  2822. free(*ppwsz);
  2823. *ppwsz=NULL;
  2824. }
  2825. fResult=FALSE;
  2826. goto CommonReturn;
  2827. TRACE_ERROR(LoadStringError);
  2828. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  2829. TRACE_ERROR(SZtoWSZError);
  2830. TRACE_ERROR(GetNumberError);
  2831. SET_ERROR(InvalidArg, E_INVALIDARG);
  2832. TRACE_ERROR(DecodeGenericError);
  2833. }
  2834. //--------------------------------------------------------------------------
  2835. //
  2836. // FormatCertQualifier:
  2837. //--------------------------------------------------------------------------
  2838. BOOL FormatCertQualifier(
  2839. DWORD dwCertEncodingType,
  2840. DWORD dwFormatType,
  2841. DWORD dwFormatStrType,
  2842. void *pFormatStruct,
  2843. PCERT_POLICY_QUALIFIER_INFO pInfo,
  2844. LPWSTR *ppwszFormat)
  2845. {
  2846. BOOL fResult=FALSE;
  2847. DWORD cbNeeded=0;
  2848. UINT ids=0;
  2849. PCCRYPT_OID_INFO pOIDInfo=NULL;
  2850. LPWSTR pwszName=NULL;
  2851. LPWSTR pwszElement=NULL;
  2852. LPWSTR pwszOID=NULL;
  2853. *ppwszFormat=NULL;
  2854. //get the oid name
  2855. pOIDInfo=CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
  2856. pInfo->pszPolicyQualifierId,
  2857. 0);
  2858. if(NULL == pOIDInfo)
  2859. {
  2860. if(S_OK!=SZtoWSZ(pInfo->pszPolicyQualifierId, &pwszOID))
  2861. goto SZtoWSZError;
  2862. }
  2863. if(pInfo->Qualifier.cbData)
  2864. {
  2865. if(0==strcmp(szOID_PKIX_POLICY_QUALIFIER_CPS, pInfo->pszPolicyQualifierId))
  2866. {
  2867. //this is just a unicode format
  2868. //turn off the multi line here
  2869. cbNeeded=0;
  2870. if(!FormatAnyUnicodeStringExtension(
  2871. dwCertEncodingType,
  2872. dwFormatType,
  2873. dwFormatStrType & (~CRYPT_FORMAT_STR_MULTI_LINE),
  2874. pFormatStruct,
  2875. pInfo->pszPolicyQualifierId,
  2876. pInfo->Qualifier.pbData,
  2877. pInfo->Qualifier.cbData,
  2878. NULL,
  2879. &cbNeeded))
  2880. goto FormatUnicodeError;
  2881. pwszName=(LPWSTR)malloc(cbNeeded);
  2882. if(NULL==pwszName)
  2883. goto MemoryError;
  2884. if(!FormatAnyUnicodeStringExtension(
  2885. dwCertEncodingType,
  2886. dwFormatType,
  2887. dwFormatStrType & (~CRYPT_FORMAT_STR_MULTI_LINE),
  2888. pFormatStruct,
  2889. pInfo->pszPolicyQualifierId,
  2890. pInfo->Qualifier.pbData,
  2891. pInfo->Qualifier.cbData,
  2892. pwszName,
  2893. &cbNeeded))
  2894. goto FormatUnicodeError;
  2895. }
  2896. else
  2897. {
  2898. if(0==strcmp(szOID_PKIX_POLICY_QUALIFIER_USERNOTICE,pInfo->pszPolicyQualifierId))
  2899. {
  2900. //this is yet another struct to format. We remember to have
  2901. //a 3 tab prefix
  2902. if(!FormatPolicyUserNotice(
  2903. dwCertEncodingType,
  2904. dwFormatType,
  2905. dwFormatStrType,
  2906. pFormatStruct,
  2907. IDS_THREE_TABS,
  2908. pInfo->Qualifier.pbData,
  2909. pInfo->Qualifier.cbData,
  2910. &pwszName))
  2911. goto FormatUserNoticdeError;
  2912. }
  2913. else
  2914. {
  2915. //get the Hex dump of the Key Usage
  2916. cbNeeded=0;
  2917. if(!FormatBytesToHex(
  2918. dwCertEncodingType,
  2919. dwFormatType,
  2920. dwFormatStrType,
  2921. pFormatStruct,
  2922. NULL,
  2923. pInfo->Qualifier.pbData,
  2924. pInfo->Qualifier.cbData,
  2925. NULL,
  2926. &cbNeeded))
  2927. goto FormatBytesToHexError;
  2928. pwszName=(LPWSTR)malloc(cbNeeded);
  2929. if(NULL==pwszName)
  2930. goto MemoryError;
  2931. if(!FormatBytesToHex(
  2932. dwCertEncodingType,
  2933. dwFormatType,
  2934. dwFormatStrType,
  2935. pFormatStruct,
  2936. NULL,
  2937. pInfo->Qualifier.pbData,
  2938. pInfo->Qualifier.cbData,
  2939. pwszName,
  2940. &cbNeeded))
  2941. goto FormatBytesToHexError;
  2942. }
  2943. }
  2944. //add the desired 3 tab prefix and new line for CSP and the new line
  2945. //for the multi line case
  2946. if((dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) &&
  2947. (0!=strcmp(szOID_PKIX_POLICY_QUALIFIER_USERNOTICE,pInfo->pszPolicyQualifierId)))
  2948. {
  2949. if(!FormatMessageUnicode(&pwszElement, IDS_POLICY_QUALIFIER_ELEMENT,
  2950. pwszName))
  2951. goto FormatMsgError;
  2952. }
  2953. //decide between single line and mulitple line format
  2954. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  2955. ids=IDS_POLICY_QUALIFIER_MULTI;
  2956. else
  2957. ids=IDS_POLICY_QUALIFIER;
  2958. if(!FormatMessageUnicode(ppwszFormat, ids,
  2959. pOIDInfo? pOIDInfo->pwszName : pwszOID,
  2960. pwszElement? pwszElement : pwszName))
  2961. goto FormatMsgError;
  2962. }
  2963. else
  2964. {
  2965. //decide between single line and mulitple line format
  2966. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  2967. ids=IDS_POLICY_QUALIFIER_NO_BLOB_MULTI;
  2968. else
  2969. ids=IDS_POLICY_QUALIFIER_NO_BLOB;
  2970. if(!FormatMessageUnicode(ppwszFormat, ids,
  2971. pOIDInfo? pOIDInfo->pwszName : pwszOID))
  2972. goto FormatMsgError;
  2973. }
  2974. fResult=TRUE;
  2975. CommonReturn:
  2976. if(pwszName)
  2977. free(pwszName);
  2978. if(pwszElement)
  2979. LocalFree((HLOCAL)pwszElement);
  2980. if(pwszOID)
  2981. free(pwszOID);
  2982. return fResult;
  2983. ErrorReturn:
  2984. if(*ppwszFormat)
  2985. {
  2986. LocalFree((HLOCAL)(*ppwszFormat));
  2987. *ppwszFormat=NULL;
  2988. }
  2989. fResult=FALSE;
  2990. goto CommonReturn;
  2991. TRACE_ERROR(FormatBytesToHexError);
  2992. TRACE_ERROR(FormatMsgError);
  2993. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  2994. TRACE_ERROR(FormatUnicodeError);
  2995. TRACE_ERROR(FormatUserNoticdeError);
  2996. TRACE_ERROR(SZtoWSZError);
  2997. }
  2998. //--------------------------------------------------------------------------
  2999. //
  3000. // FormatCertPolicies: X509_CERT_POLICIES
  3001. // szOID_CERT_POLICIES
  3002. // szOID_APPLICATION_CERT_POLICIES
  3003. //
  3004. //--------------------------------------------------------------------------
  3005. static BOOL
  3006. WINAPI
  3007. FormatCertPolicies(
  3008. DWORD dwCertEncodingType,
  3009. DWORD dwFormatType,
  3010. DWORD dwFormatStrType,
  3011. void *pFormatStruct,
  3012. LPCSTR lpszStructType,
  3013. const BYTE *pbEncoded,
  3014. DWORD cbEncoded,
  3015. void *pbFormat,
  3016. DWORD *pcbFormat)
  3017. {
  3018. LPWSTR pwszFormat=NULL;
  3019. LPWSTR pwsz=NULL;
  3020. LPWSTR pwszPolicyFormat=NULL;
  3021. LPWSTR pwszQualifiers=NULL;
  3022. LPWSTR pwszQualifierFormat=NULL;
  3023. LPWSTR pwszOneQualifier=NULL;
  3024. LPWSTR pwszOID=NULL;
  3025. PCERT_POLICIES_INFO pInfo=NULL;
  3026. PCERT_POLICY_INFO pPolicyInfo=NULL;
  3027. DWORD dwIndex=0;
  3028. DWORD dwQualifierIndex=0;
  3029. DWORD cbNeeded=0;
  3030. BOOL fResult=FALSE;
  3031. UINT ids=0;
  3032. PCCRYPT_OID_INFO pOIDInfo=NULL;
  3033. LPWSTR pwszTemp;
  3034. //check for input parameters
  3035. if((NULL==pbEncoded&& cbEncoded!=0) ||
  3036. (NULL==pcbFormat))
  3037. goto InvalidArg;
  3038. if(cbEncoded==0)
  3039. {
  3040. *pcbFormat=0;
  3041. goto InvalidArg;
  3042. }
  3043. if (!DecodeGenericBLOB(dwCertEncodingType,X509_CERT_POLICIES,
  3044. pbEncoded,cbEncoded, (void **)&pInfo))
  3045. goto DecodeGenericError;
  3046. pwsz=(LPWSTR)malloc(sizeof(WCHAR));
  3047. if(NULL==pwsz)
  3048. goto MemoryError;
  3049. *pwsz=L'\0';
  3050. for(dwIndex=0; dwIndex < pInfo->cPolicyInfo; dwIndex++)
  3051. {
  3052. //strcat ", "
  3053. if(0!=wcslen(pwsz))
  3054. {
  3055. if(0==(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
  3056. wcscat(pwsz, wszCOMMA);
  3057. }
  3058. pPolicyInfo=&(pInfo->rgPolicyInfo[dwIndex]);
  3059. pwszQualifiers=(LPWSTR)malloc(sizeof(WCHAR));
  3060. if(NULL==pwszQualifiers)
  3061. goto MemoryError;
  3062. *pwszQualifiers=L'\0';
  3063. //format the qualifiers
  3064. for(dwQualifierIndex=0; dwQualifierIndex < pPolicyInfo->cPolicyQualifier;
  3065. dwQualifierIndex++)
  3066. {
  3067. //strcat ", "
  3068. if(0!=wcslen(pwszQualifiers))
  3069. {
  3070. if(0==(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
  3071. wcscat(pwszQualifiers, wszCOMMA);
  3072. }
  3073. if(!FormatCertQualifier(dwCertEncodingType,
  3074. dwFormatType,
  3075. dwFormatStrType,
  3076. pFormatStruct,
  3077. &(pPolicyInfo->rgPolicyQualifier[dwQualifierIndex]),
  3078. &pwszOneQualifier))
  3079. goto FormatCertQualifierError;
  3080. //decide between single line and mulitple line format
  3081. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  3082. ids=IDS_POLICY_QUALIFIER_INFO_MULTI;
  3083. else
  3084. ids=IDS_POLICY_QUALIFIER_INFO;
  3085. //format
  3086. if(!FormatMessageUnicode(&pwszQualifierFormat,ids,
  3087. dwIndex+1,
  3088. dwQualifierIndex+1,
  3089. pwszOneQualifier))
  3090. goto FormatMsgError;
  3091. //strcat
  3092. #if (0) // DSIE: Bug 27436
  3093. pwszQualifiers=(LPWSTR)realloc(pwszQualifiers,
  3094. sizeof(WCHAR) * (wcslen(pwszQualifiers)+wcslen(wszCOMMA)+wcslen(pwszQualifierFormat)+1));
  3095. if(NULL==pwszQualifiers)
  3096. goto MemoryError;
  3097. #endif
  3098. pwszTemp=(LPWSTR)realloc(pwszQualifiers,
  3099. sizeof(WCHAR) * (wcslen(pwszQualifiers)+wcslen(wszCOMMA)+wcslen(pwszQualifierFormat)+1));
  3100. if(NULL==pwszTemp)
  3101. goto MemoryError;
  3102. pwszQualifiers = pwszTemp;
  3103. wcscat(pwszQualifiers, pwszQualifierFormat);
  3104. LocalFree((HLOCAL)pwszOneQualifier);
  3105. pwszOneQualifier=NULL;
  3106. LocalFree((HLOCAL)pwszQualifierFormat);
  3107. pwszQualifierFormat=NULL;
  3108. }
  3109. //now, format the certPolicyInfo
  3110. pOIDInfo=CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
  3111. pPolicyInfo->pszPolicyIdentifier,
  3112. 0);
  3113. if(NULL == pOIDInfo)
  3114. {
  3115. if(S_OK!=SZtoWSZ(pPolicyInfo->pszPolicyIdentifier, &pwszOID))
  3116. goto SZtoWSZError;
  3117. }
  3118. if(0!=pPolicyInfo->cPolicyQualifier)
  3119. {
  3120. //decide between single line and mulitple line format
  3121. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  3122. if (0 == strcmp(lpszStructType, szOID_CERT_POLICIES))
  3123. ids=IDS_CERT_POLICY_MULTI;
  3124. else
  3125. ids=IDS_APPLICATION_CERT_POLICY_MULTI;
  3126. else
  3127. if (0 == strcmp(lpszStructType, szOID_CERT_POLICIES))
  3128. ids=IDS_CERT_POLICY;
  3129. else
  3130. ids=IDS_APPLICATION_CERT_POLICY;
  3131. if(!FormatMessageUnicode(&pwszPolicyFormat,ids,
  3132. dwIndex+1, pOIDInfo? pOIDInfo->pwszName : pwszOID,
  3133. pwszQualifiers))
  3134. goto FormatMsgError;
  3135. }
  3136. else
  3137. {
  3138. //decide between single line and mulitple line format
  3139. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  3140. if (0 == strcmp(lpszStructType, szOID_CERT_POLICIES))
  3141. ids=IDS_CERT_POLICY_NO_QUA_MULTI;
  3142. else
  3143. ids=IDS_APPLICATION_CERT_POLICY_NO_QUA_MULTI;
  3144. else
  3145. if (0 == strcmp(lpszStructType, szOID_CERT_POLICIES))
  3146. ids=IDS_CERT_POLICY_NO_QUA;
  3147. else
  3148. ids=IDS_APPLICATION_CERT_POLICY_NO_QUA;
  3149. if(!FormatMessageUnicode(&pwszPolicyFormat, ids,
  3150. dwIndex+1, pOIDInfo? pOIDInfo->pwszName : pwszOID))
  3151. goto FormatMsgError;
  3152. }
  3153. //strcat
  3154. #if (0) // DSIE: Bug 27436
  3155. pwsz=(LPWSTR)realloc(pwsz,
  3156. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszPolicyFormat)+1));
  3157. if(NULL==pwsz)
  3158. goto MemoryError;
  3159. #endif
  3160. pwszTemp=(LPWSTR)realloc(pwsz,
  3161. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszPolicyFormat)+1));
  3162. if(NULL==pwszTemp)
  3163. goto MemoryError;
  3164. pwsz = pwszTemp;
  3165. wcscat(pwsz, pwszPolicyFormat);
  3166. free(pwszQualifiers);
  3167. pwszQualifiers=NULL;
  3168. LocalFree((HLOCAL)pwszPolicyFormat);
  3169. pwszPolicyFormat=NULL;
  3170. if(pwszOID)
  3171. free(pwszOID);
  3172. pwszOID=NULL;
  3173. }
  3174. if(0==wcslen(pwsz))
  3175. {
  3176. //no data
  3177. pwszFormat=(LPWSTR)malloc(sizeof(WCHAR)*(NO_INFO_SIZE+1));
  3178. if(NULL==pwszFormat)
  3179. goto MemoryError;
  3180. if(!LoadStringU(hFrmtFuncInst,IDS_NO_INFO, pwszFormat, NO_INFO_SIZE))
  3181. goto LoadStringError;
  3182. }
  3183. else
  3184. {
  3185. pwszFormat=pwsz;
  3186. pwsz=NULL;
  3187. }
  3188. cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
  3189. //length only calculation
  3190. if(NULL==pbFormat)
  3191. {
  3192. *pcbFormat=cbNeeded;
  3193. fResult=TRUE;
  3194. goto CommonReturn;
  3195. }
  3196. if((*pcbFormat)<cbNeeded)
  3197. {
  3198. *pcbFormat=cbNeeded;
  3199. goto MoreDataError;
  3200. }
  3201. //copy the data
  3202. memcpy(pbFormat, pwszFormat, cbNeeded);
  3203. //copy the size
  3204. *pcbFormat=cbNeeded;
  3205. fResult=TRUE;
  3206. CommonReturn:
  3207. if(pwszOID)
  3208. free(pwszOID);
  3209. if(pwszOneQualifier)
  3210. LocalFree((HLOCAL)pwszOneQualifier);
  3211. if(pwszQualifierFormat)
  3212. LocalFree((HLOCAL)pwszQualifierFormat);
  3213. if(pwszQualifiers)
  3214. free(pwszQualifiers);
  3215. if(pwszPolicyFormat)
  3216. LocalFree((HLOCAL)pwszPolicyFormat);
  3217. if(pwsz)
  3218. free(pwsz);
  3219. if(pwszFormat)
  3220. free(pwszFormat);
  3221. if(pInfo)
  3222. free(pInfo);
  3223. return fResult;
  3224. ErrorReturn:
  3225. fResult=FALSE;
  3226. goto CommonReturn;
  3227. SET_ERROR(InvalidArg, E_INVALIDARG);
  3228. TRACE_ERROR(DecodeGenericError);
  3229. TRACE_ERROR(LoadStringError);
  3230. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  3231. TRACE_ERROR(FormatMsgError);
  3232. SET_ERROR(MemoryError,E_OUTOFMEMORY);
  3233. TRACE_ERROR(FormatCertQualifierError);
  3234. TRACE_ERROR(SZtoWSZError);
  3235. }
  3236. //--------------------------------------------------------------------------
  3237. //
  3238. // FormatCAVersion: szOID_CERTSRV_CA_VERSION
  3239. // Decode as X509_INTEGER
  3240. //
  3241. //--------------------------------------------------------------------------
  3242. static BOOL
  3243. WINAPI
  3244. FormatCAVersion(
  3245. DWORD dwCertEncodingType,
  3246. DWORD dwFormatType,
  3247. DWORD dwFormatStrType,
  3248. void *pFormatStruct,
  3249. LPCSTR lpszStructType,
  3250. const BYTE *pbEncoded,
  3251. DWORD cbEncoded,
  3252. void *pbFormat,
  3253. DWORD *pcbFormat)
  3254. {
  3255. BOOL fResult=FALSE;
  3256. DWORD cbNeeded=0;
  3257. UINT ids=0;
  3258. DWORD dwCAVersion=0;
  3259. DWORD cbCAVersion=sizeof(dwCAVersion);
  3260. LPWSTR pwszFormat=NULL;
  3261. //check for input parameters
  3262. if((NULL==pbEncoded && 0!=cbEncoded) ||
  3263. (NULL==pcbFormat))
  3264. goto InvalidArg;
  3265. if(cbEncoded==0)
  3266. {
  3267. *pcbFormat=0;
  3268. goto InvalidArg;
  3269. }
  3270. if(!CryptDecodeObject(dwCertEncodingType,X509_INTEGER,pbEncoded, cbEncoded,
  3271. 0,&dwCAVersion,&cbCAVersion))
  3272. goto DecodeGenericError;
  3273. //decide between single line and mulitple line format
  3274. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  3275. ids=IDS_CA_VERSION_MULTI;
  3276. else
  3277. ids=IDS_CA_VERSION;
  3278. if(!FormatMessageUnicode(&pwszFormat, ids,
  3279. CANAMEIDTOICERT(dwCAVersion), CANAMEIDTOIKEY(dwCAVersion)))
  3280. goto FormatMsgError;
  3281. cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
  3282. //length only calculation
  3283. if(NULL==pbFormat)
  3284. {
  3285. *pcbFormat=cbNeeded;
  3286. fResult=TRUE;
  3287. goto CommonReturn;
  3288. }
  3289. if((*pcbFormat)<cbNeeded)
  3290. {
  3291. *pcbFormat=cbNeeded;
  3292. goto MoreDataError;
  3293. }
  3294. //copy the data
  3295. memcpy(pbFormat, pwszFormat, cbNeeded);
  3296. //copy the size
  3297. *pcbFormat=cbNeeded;
  3298. fResult=TRUE;
  3299. CommonReturn:
  3300. if(pwszFormat)
  3301. LocalFree((HLOCAL)pwszFormat);
  3302. return fResult;
  3303. ErrorReturn:
  3304. fResult=FALSE;
  3305. goto CommonReturn;
  3306. SET_ERROR(InvalidArg, E_INVALIDARG);
  3307. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  3308. TRACE_ERROR(DecodeGenericError);
  3309. TRACE_ERROR(FormatMsgError);
  3310. }
  3311. //--------------------------------------------------------------------------
  3312. //
  3313. // FormatNetscapeCertType:
  3314. // szOID_NETSCAPE_CERT_TYPE
  3315. // Decode as X509_BITS
  3316. //
  3317. //--------------------------------------------------------------------------
  3318. static BOOL
  3319. WINAPI
  3320. FormatNetscapeCertType(
  3321. DWORD dwCertEncodingType,
  3322. DWORD dwFormatType,
  3323. DWORD dwFormatStrType,
  3324. void *pFormatStruct,
  3325. LPCSTR lpszStructType,
  3326. const BYTE *pbEncoded,
  3327. DWORD cbEncoded,
  3328. void *pbFormat,
  3329. DWORD *pcbFormat)
  3330. {
  3331. BOOL fResult=FALSE;
  3332. DWORD cbNeeded=0;
  3333. WCHAR wszCertType[CERT_TYPE_SIZE+1];
  3334. FORMAT_CERT_TYPE_INFO rgCertType[]={
  3335. NETSCAPE_SSL_CLIENT_AUTH_CERT_TYPE, IDS_NETSCAPE_SSL_CLIENT_AUTH, //0x80
  3336. NETSCAPE_SSL_SERVER_AUTH_CERT_TYPE, IDS_NETSCAPE_SSL_SERVER_AUTH, //0x40
  3337. NETSCAPE_SMIME_CERT_TYPE, IDS_NETSCAPE_SMIME, //0x20
  3338. NETSCAPE_SIGN_CERT_TYPE, IDS_NETSCAPE_SIGN, //0x10
  3339. 0x08, IDS_UNKNOWN_CERT_TYPE, //0x08
  3340. NETSCAPE_SSL_CA_CERT_TYPE, IDS_NETSCAPE_SSL_CA, //0x04
  3341. NETSCAPE_SMIME_CA_CERT_TYPE, IDS_NETSCAPE_SMIME_CA, //0x02
  3342. NETSCAPE_SIGN_CA_CERT_TYPE, IDS_NETSCAPE_SIGN_CA}; //0x01
  3343. DWORD dwCertType=0;
  3344. DWORD dwIndex=0;
  3345. CRYPT_BIT_BLOB *pInfo=NULL;
  3346. LPWSTR pwsz=NULL;
  3347. LPWSTR pwszByte=NULL;
  3348. LPWSTR pwszFormat=NULL;
  3349. LPWSTR pwszTemp;
  3350. //check for input parameters
  3351. if((NULL==pbEncoded && 0!=cbEncoded) ||
  3352. (NULL==pcbFormat))
  3353. goto InvalidArg;
  3354. if(cbEncoded==0)
  3355. {
  3356. *pcbFormat=0;
  3357. goto InvalidArg;
  3358. }
  3359. if(!DecodeGenericBLOB(dwCertEncodingType,X509_BITS,
  3360. pbEncoded,cbEncoded, (void **)&pInfo))
  3361. goto DecodeGenericError;
  3362. if(0==pInfo->cbData)
  3363. goto InvalidArg;
  3364. pwsz=(LPWSTR)malloc(sizeof(WCHAR));
  3365. if(NULL==pwsz)
  3366. goto MemoryError;
  3367. *pwsz=L'\0';
  3368. //the count of bits to consider
  3369. dwCertType=sizeof(rgCertType)/sizeof(rgCertType[0]);
  3370. //we need to consider the unused bits in the last byte
  3371. if((1 == pInfo->cbData) && (8 > pInfo->cUnusedBits))
  3372. {
  3373. dwCertType=8-pInfo->cUnusedBits;
  3374. }
  3375. for(dwIndex=0; dwIndex<dwCertType; dwIndex++)
  3376. {
  3377. if(pInfo->pbData[0] & rgCertType[dwIndex].bCertType)
  3378. {
  3379. if(!LoadStringU(hFrmtFuncInst, rgCertType[dwIndex].idsCertType, wszCertType, CERT_TYPE_SIZE))
  3380. goto LoadStringError;
  3381. #if (0) // DSIE: Bug 27436
  3382. pwsz=(LPWSTR)realloc(pwsz,
  3383. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCertType)+1+wcslen(wszCOMMA)));
  3384. if(NULL==pwsz)
  3385. goto MemoryError;
  3386. #endif
  3387. pwszTemp=(LPWSTR)realloc(pwsz,
  3388. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCertType)+1+wcslen(wszCOMMA)));
  3389. if(NULL==pwszTemp)
  3390. goto MemoryError;
  3391. pwsz = pwszTemp;
  3392. wcscat(pwsz, wszCertType);
  3393. wcscat(pwsz, wszCOMMA);
  3394. }
  3395. }
  3396. //there is data that we can not interpret if the bit number is more than 8
  3397. if(8 < (8 * pInfo->cbData - pInfo->cUnusedBits))
  3398. {
  3399. if(!LoadStringU(hFrmtFuncInst, IDS_UNKNOWN_CERT_TYPE, wszCertType, CERT_TYPE_SIZE))
  3400. goto LoadStringError;
  3401. #if (0) // DSIE: Bug 27436
  3402. pwsz=(LPWSTR)realloc(pwsz,
  3403. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCertType)+1+wcslen(wszCOMMA)));
  3404. if(NULL==pwsz)
  3405. goto MemoryError;
  3406. #endif
  3407. pwszTemp=(LPWSTR)realloc(pwsz,
  3408. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCertType)+1+wcslen(wszCOMMA)));
  3409. if(NULL==pwszTemp)
  3410. goto MemoryError;
  3411. pwsz = pwszTemp;
  3412. wcscat(pwsz, wszCertType);
  3413. wcscat(pwsz, wszCOMMA);
  3414. }
  3415. if(0==wcslen(pwsz))
  3416. {
  3417. #if (0) // DSIE: Bug 27436
  3418. pwsz=(LPWSTR)realloc(pwsz, sizeof(WCHAR) * (CERT_TYPE_SIZE+1));
  3419. if(NULL == pwsz)
  3420. goto MemoryError;
  3421. #endif
  3422. pwszTemp=(LPWSTR)realloc(pwsz, sizeof(WCHAR) * (CERT_TYPE_SIZE+1));
  3423. if(NULL == pwszTemp)
  3424. goto MemoryError;
  3425. pwsz = pwszTemp;
  3426. if(!LoadStringU(hFrmtFuncInst, IDS_UNKNOWN_CERT_TYPE, pwsz,
  3427. CERT_TYPE_SIZE))
  3428. goto LoadStringError;
  3429. }
  3430. else
  3431. {
  3432. //get rid of the last comma
  3433. *(pwsz+wcslen(pwsz)-wcslen(wszCOMMA))=L'\0';
  3434. }
  3435. //get the Hex dump of the cert type
  3436. cbNeeded=0;
  3437. if(!FormatBytesToHex(
  3438. dwCertEncodingType,
  3439. dwFormatType,
  3440. dwFormatStrType,
  3441. pFormatStruct,
  3442. lpszStructType,
  3443. pInfo->pbData,
  3444. pInfo->cbData,
  3445. NULL,
  3446. &cbNeeded))
  3447. goto FormatBytesToHexError;
  3448. pwszByte=(LPWSTR)malloc(cbNeeded);
  3449. if(NULL==pwszByte)
  3450. goto MemoryError;
  3451. if(!FormatBytesToHex(
  3452. dwCertEncodingType,
  3453. dwFormatType,
  3454. dwFormatStrType,
  3455. pFormatStruct,
  3456. lpszStructType,
  3457. pInfo->pbData,
  3458. pInfo->cbData,
  3459. pwszByte,
  3460. &cbNeeded))
  3461. goto FormatBytesToHexError;
  3462. //convert the WSZ
  3463. if(!FormatMessageUnicode(&pwszFormat, IDS_BIT_BLOB, pwsz,
  3464. pwszByte))
  3465. goto FormatMsgError;
  3466. cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
  3467. //length only calculation
  3468. if(NULL==pbFormat)
  3469. {
  3470. *pcbFormat=cbNeeded;
  3471. fResult=TRUE;
  3472. goto CommonReturn;
  3473. }
  3474. if((*pcbFormat)<cbNeeded)
  3475. {
  3476. *pcbFormat=cbNeeded;
  3477. goto MoreDataError;
  3478. }
  3479. //copy the data
  3480. memcpy(pbFormat, pwszFormat, cbNeeded);
  3481. //copy the size
  3482. *pcbFormat=cbNeeded;
  3483. fResult=TRUE;
  3484. CommonReturn:
  3485. if(pInfo)
  3486. free(pInfo);
  3487. if(pwsz)
  3488. free(pwsz);
  3489. if(pwszByte)
  3490. free(pwszByte);
  3491. if(pwszFormat)
  3492. LocalFree((HLOCAL)pwszFormat);
  3493. return fResult;
  3494. ErrorReturn:
  3495. fResult=FALSE;
  3496. goto CommonReturn;
  3497. SET_ERROR(InvalidArg, E_INVALIDARG);
  3498. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  3499. TRACE_ERROR(DecodeGenericError);
  3500. TRACE_ERROR(FormatMsgError);
  3501. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  3502. TRACE_ERROR(FormatBytesToHexError);
  3503. TRACE_ERROR(LoadStringError);
  3504. }
  3505. //--------------------------------------------------------------------------
  3506. //
  3507. // FormatAnyUnicodeStringExtension:
  3508. // szOID_ENROLLMENT_NAME_VALUE_PAIR
  3509. // Decode as szOID_ENROLLMENT_NAME_VALUE_PAIR
  3510. //
  3511. //--------------------------------------------------------------------------
  3512. static BOOL
  3513. WINAPI
  3514. FormatAnyNameValueStringAttr(
  3515. DWORD dwCertEncodingType,
  3516. DWORD dwFormatType,
  3517. DWORD dwFormatStrType,
  3518. void *pFormatStruct,
  3519. LPCSTR lpszStructType,
  3520. const BYTE *pbEncoded,
  3521. DWORD cbEncoded,
  3522. void *pbFormat,
  3523. DWORD *pcbFormat)
  3524. {
  3525. BOOL fResult=FALSE;
  3526. DWORD cbNeeded=0;
  3527. UINT ids=0;
  3528. CRYPT_ENROLLMENT_NAME_VALUE_PAIR *pInfo=NULL;
  3529. LPWSTR pwszFormat=NULL;
  3530. //check for input parameters
  3531. if((NULL==pbEncoded && 0!=cbEncoded) ||
  3532. (NULL==pcbFormat))
  3533. goto InvalidArg;
  3534. if(cbEncoded==0)
  3535. {
  3536. *pcbFormat=0;
  3537. goto InvalidArg;
  3538. }
  3539. if (!DecodeGenericBLOB(dwCertEncodingType,szOID_ENROLLMENT_NAME_VALUE_PAIR,
  3540. pbEncoded,cbEncoded, (void **)&pInfo))
  3541. goto DecodeGenericError;
  3542. if(NULL == pInfo->pwszName || NULL == pInfo->pwszValue)
  3543. goto InvalidArg;
  3544. //decide between single line and mulitple line format
  3545. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  3546. ids=IDS_NAME_VALUE_MULTI;
  3547. else
  3548. ids=IDS_NAME_VALUE;
  3549. if(!FormatMessageUnicode(&pwszFormat, ids,
  3550. pInfo->pwszName, pInfo->pwszValue))
  3551. goto FormatMsgError;
  3552. cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
  3553. //length only calculation
  3554. if(NULL==pbFormat)
  3555. {
  3556. *pcbFormat=cbNeeded;
  3557. fResult=TRUE;
  3558. goto CommonReturn;
  3559. }
  3560. if((*pcbFormat)<cbNeeded)
  3561. {
  3562. *pcbFormat=cbNeeded;
  3563. goto MoreDataError;
  3564. }
  3565. //copy the data
  3566. memcpy(pbFormat, pwszFormat, cbNeeded);
  3567. //copy the size
  3568. *pcbFormat=cbNeeded;
  3569. fResult=TRUE;
  3570. CommonReturn:
  3571. if(pInfo)
  3572. free(pInfo);
  3573. if(pwszFormat)
  3574. LocalFree((HLOCAL)pwszFormat);
  3575. return fResult;
  3576. ErrorReturn:
  3577. fResult=FALSE;
  3578. goto CommonReturn;
  3579. SET_ERROR(InvalidArg, E_INVALIDARG);
  3580. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  3581. TRACE_ERROR(DecodeGenericError);
  3582. TRACE_ERROR(FormatMsgError);
  3583. }
  3584. //--------------------------------------------------------------------------
  3585. //
  3586. // FormatAnyUnicodeStringExtension:
  3587. // szOID_ENROLL_CERTTYPE_EXTENSION
  3588. // szOID_NETSCAPE_REVOCATION_URL
  3589. // Decode as X509_ANY_UNICODE_STRING
  3590. //
  3591. //--------------------------------------------------------------------------
  3592. static BOOL
  3593. WINAPI
  3594. FormatAnyUnicodeStringExtension(
  3595. DWORD dwCertEncodingType,
  3596. DWORD dwFormatType,
  3597. DWORD dwFormatStrType,
  3598. void *pFormatStruct,
  3599. LPCSTR lpszStructType,
  3600. const BYTE *pbEncoded,
  3601. DWORD cbEncoded,
  3602. void *pbFormat,
  3603. DWORD *pcbFormat)
  3604. {
  3605. BOOL fResult=FALSE;
  3606. DWORD cbNeeded=0;
  3607. UINT ids=0;
  3608. CERT_NAME_VALUE *pInfo=NULL;
  3609. LPWSTR pwszFormat=NULL;
  3610. //check for input parameters
  3611. if((NULL==pbEncoded && 0!=cbEncoded) ||
  3612. (NULL==pcbFormat))
  3613. goto InvalidArg;
  3614. if(cbEncoded==0)
  3615. {
  3616. *pcbFormat=0;
  3617. goto InvalidArg;
  3618. }
  3619. if (!DecodeGenericBLOB(dwCertEncodingType,X509_UNICODE_ANY_STRING,
  3620. pbEncoded,cbEncoded, (void **)&pInfo))
  3621. goto DecodeGenericError;
  3622. //the data can not be the encoded blob or the octect string
  3623. if(!IS_CERT_RDN_CHAR_STRING(pInfo->dwValueType))
  3624. goto DecodeGenericError;
  3625. //decide between single line and mulitple line format
  3626. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  3627. ids=IDS_UNICODE_STRING_MULTI;
  3628. else
  3629. ids=IDS_UNICODE_STRING;
  3630. if(!FormatMessageUnicode(&pwszFormat, ids,
  3631. (LPWSTR)(pInfo->Value.pbData)))
  3632. goto FormatMsgError;
  3633. cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
  3634. //length only calculation
  3635. if(NULL==pbFormat)
  3636. {
  3637. *pcbFormat=cbNeeded;
  3638. fResult=TRUE;
  3639. goto CommonReturn;
  3640. }
  3641. if((*pcbFormat)<cbNeeded)
  3642. {
  3643. *pcbFormat=cbNeeded;
  3644. goto MoreDataError;
  3645. }
  3646. //copy the data
  3647. memcpy(pbFormat, pwszFormat, cbNeeded);
  3648. //copy the size
  3649. *pcbFormat=cbNeeded;
  3650. fResult=TRUE;
  3651. CommonReturn:
  3652. if(pInfo)
  3653. free(pInfo);
  3654. if(pwszFormat)
  3655. LocalFree((HLOCAL)pwszFormat);
  3656. return fResult;
  3657. ErrorReturn:
  3658. fResult=FALSE;
  3659. goto CommonReturn;
  3660. SET_ERROR(InvalidArg, E_INVALIDARG);
  3661. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  3662. TRACE_ERROR(DecodeGenericError);
  3663. TRACE_ERROR(FormatMsgError);
  3664. }
  3665. //--------------------------------------------------------------------------
  3666. //
  3667. // FormatDistPointName: Pre-condition: dwDistPointNameChoice!=0
  3668. //--------------------------------------------------------------------------
  3669. BOOL FormatDistPointName(DWORD dwCertEncodingType,
  3670. DWORD dwFormatType,
  3671. DWORD dwFormatStrType,
  3672. void *pFormatStruct,
  3673. PCRL_DIST_POINT_NAME pInfo,
  3674. LPWSTR *ppwszFormat)
  3675. {
  3676. BOOL fResult=FALSE;
  3677. DWORD cbNeeded=0;
  3678. LPWSTR pwszCRLIssuer=NULL;
  3679. UINT ids=0;
  3680. *ppwszFormat=NULL;
  3681. if(CRL_DIST_POINT_FULL_NAME==pInfo->dwDistPointNameChoice)
  3682. {
  3683. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  3684. ids=IDS_THREE_TABS;
  3685. cbNeeded=0;
  3686. if(!FormatAltNameInfo(dwCertEncodingType,
  3687. dwFormatType,
  3688. dwFormatStrType,
  3689. pFormatStruct,
  3690. ids,
  3691. FALSE,
  3692. &(pInfo->FullName),
  3693. NULL,
  3694. &cbNeeded))
  3695. goto FormatAltNameError;
  3696. pwszCRLIssuer=(LPWSTR)malloc(cbNeeded);
  3697. if(NULL==pwszCRLIssuer)
  3698. goto MemoryError;
  3699. if(!FormatAltNameInfo(dwCertEncodingType,
  3700. dwFormatType,
  3701. dwFormatStrType,
  3702. pFormatStruct,
  3703. ids,
  3704. FALSE,
  3705. &(pInfo->FullName),
  3706. pwszCRLIssuer,
  3707. &cbNeeded))
  3708. goto FormatAltNameError;
  3709. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  3710. ids=IDS_CRL_DIST_FULL_NAME_MULTI;
  3711. else
  3712. ids=IDS_CRL_DIST_FULL_NAME;
  3713. if(!FormatMessageUnicode(ppwszFormat, ids,pwszCRLIssuer))
  3714. goto FormatMsgError;
  3715. }
  3716. else if(CRL_DIST_POINT_ISSUER_RDN_NAME==pInfo->dwDistPointNameChoice)
  3717. {
  3718. *ppwszFormat=(LPWSTR)malloc(sizeof(WCHAR)*(CRL_DIST_NAME_SIZE+1));
  3719. if(NULL==*ppwszFormat)
  3720. goto MemoryError;
  3721. if(!LoadStringU(hFrmtFuncInst, IDS_CRL_DIST_ISSUER_RDN,
  3722. *ppwszFormat,CRL_DIST_NAME_SIZE))
  3723. goto LoadStringError;
  3724. }
  3725. else
  3726. {
  3727. if(!FormatMessageUnicode(ppwszFormat, IDS_DWORD,
  3728. pInfo->dwDistPointNameChoice))
  3729. goto FormatMsgError;
  3730. }
  3731. fResult=TRUE;
  3732. CommonReturn:
  3733. if(pwszCRLIssuer)
  3734. free(pwszCRLIssuer);
  3735. return fResult;
  3736. ErrorReturn:
  3737. if(*ppwszFormat)
  3738. {
  3739. LocalFree((HLOCAL)(*ppwszFormat));
  3740. *ppwszFormat=NULL;
  3741. }
  3742. fResult=FALSE;
  3743. goto CommonReturn;
  3744. TRACE_ERROR(FormatMsgError);
  3745. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  3746. TRACE_ERROR(LoadStringError);
  3747. TRACE_ERROR(FormatAltNameError);
  3748. }
  3749. //--------------------------------------------------------------------------
  3750. //
  3751. // FormatCRLReason: Pre-condition: pReason.cbData != 0
  3752. //--------------------------------------------------------------------------
  3753. BOOL FormatCRLReason(DWORD dwCertEncodingType,
  3754. DWORD dwFormatType,
  3755. DWORD dwFormatStrType,
  3756. void *pFormatStruct,
  3757. LPCSTR lpszStructType,
  3758. PCRYPT_BIT_BLOB pInfo,
  3759. LPWSTR *ppwszFormat)
  3760. {
  3761. LPWSTR pwszFormat=NULL;
  3762. LPWSTR pwszByte=NULL;
  3763. WCHAR wszReason[CRL_REASON_SIZE+1];
  3764. DWORD cbNeeded=0;
  3765. BOOL fResult=FALSE;
  3766. LPWSTR pwszTemp;
  3767. *ppwszFormat=NULL;
  3768. pwszFormat=(LPWSTR)malloc(sizeof(WCHAR));
  3769. if(NULL==pwszFormat)
  3770. goto MemoryError;
  3771. *pwszFormat=L'\0';
  3772. //format the 1st byte
  3773. if(pInfo->pbData[0] & CRL_REASON_UNUSED_FLAG)
  3774. {
  3775. if(!LoadStringU(hFrmtFuncInst, IDS_UNSPECIFIED, wszReason, CRL_REASON_SIZE))
  3776. goto LoadStringError;
  3777. #if (0) // DSIE: Bug 27436
  3778. pwszFormat=(LPWSTR)realloc(pwszFormat,
  3779. sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszReason)+1+wcslen(wszCOMMA)));
  3780. if(NULL==pwszFormat)
  3781. goto MemoryError;
  3782. #endif
  3783. pwszTemp=(LPWSTR)realloc(pwszFormat,
  3784. sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszReason)+1+wcslen(wszCOMMA)));
  3785. if(NULL==pwszTemp)
  3786. goto MemoryError;
  3787. pwszFormat = pwszTemp;
  3788. wcscat(pwszFormat, wszReason);
  3789. wcscat(pwszFormat, wszCOMMA);
  3790. }
  3791. if(pInfo->pbData[0] & CRL_REASON_KEY_COMPROMISE_FLAG)
  3792. {
  3793. if(!LoadStringU(hFrmtFuncInst, IDS_KEY_COMPROMISE, wszReason,CRL_REASON_SIZE))
  3794. goto LoadStringError;
  3795. #if (0) // DSIE: Bug 27436
  3796. pwszFormat=(LPWSTR)realloc(pwszFormat,
  3797. sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszReason)+1+wcslen(wszCOMMA)));
  3798. if(NULL==pwszFormat)
  3799. goto MemoryError;
  3800. #endif
  3801. pwszTemp=(LPWSTR)realloc(pwszFormat,
  3802. sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszReason)+1+wcslen(wszCOMMA)));
  3803. if(NULL==pwszTemp)
  3804. goto MemoryError;
  3805. pwszFormat = pwszTemp;
  3806. wcscat(pwszFormat, wszReason);
  3807. wcscat(pwszFormat, wszCOMMA);
  3808. }
  3809. if(pInfo->pbData[0] & CRL_REASON_CA_COMPROMISE_FLAG )
  3810. {
  3811. if(!LoadStringU(hFrmtFuncInst, IDS_CA_COMPROMISE,wszReason, CRL_REASON_SIZE))
  3812. goto LoadStringError;
  3813. #if (0) // DSIE: Bug 27436
  3814. pwszFormat=(LPWSTR)realloc(pwszFormat,
  3815. sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszReason)+1+wcslen(wszCOMMA)));
  3816. if(NULL==pwszFormat)
  3817. goto MemoryError;
  3818. #endif
  3819. pwszTemp=(LPWSTR)realloc(pwszFormat,
  3820. sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszReason)+1+wcslen(wszCOMMA)));
  3821. if(NULL==pwszTemp)
  3822. goto MemoryError;
  3823. pwszFormat = pwszTemp;
  3824. wcscat(pwszFormat, wszReason);
  3825. wcscat(pwszFormat, wszCOMMA);
  3826. }
  3827. if(pInfo->pbData[0] & CRL_REASON_AFFILIATION_CHANGED_FLAG )
  3828. {
  3829. if(!LoadStringU(hFrmtFuncInst, IDS_AFFILIATION_CHANGED, wszReason, CRL_REASON_SIZE))
  3830. goto LoadStringError;
  3831. #if (0) // DSIE: Bug 27436
  3832. pwszFormat=(LPWSTR)realloc(pwszFormat,
  3833. sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszReason)+1+wcslen(wszCOMMA)));
  3834. if(NULL==pwszFormat)
  3835. goto MemoryError;
  3836. #endif
  3837. pwszTemp=(LPWSTR)realloc(pwszFormat,
  3838. sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszReason)+1+wcslen(wszCOMMA)));
  3839. if(NULL==pwszTemp)
  3840. goto MemoryError;
  3841. pwszFormat = pwszTemp;
  3842. wcscat(pwszFormat, wszReason);
  3843. wcscat(pwszFormat, wszCOMMA);
  3844. }
  3845. if(pInfo->pbData[0] & CRL_REASON_SUPERSEDED_FLAG )
  3846. {
  3847. if(!LoadStringU(hFrmtFuncInst, IDS_SUPERSEDED, wszReason, CRL_REASON_SIZE))
  3848. goto LoadStringError;
  3849. #if (0) // DSIE: Bug 27436
  3850. pwszFormat=(LPWSTR)realloc(pwszFormat,
  3851. sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszReason)+1+wcslen(wszCOMMA)));
  3852. if(NULL==pwszFormat)
  3853. goto MemoryError;
  3854. #endif
  3855. pwszTemp=(LPWSTR)realloc(pwszFormat,
  3856. sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszReason)+1+wcslen(wszCOMMA)));
  3857. if(NULL==pwszTemp)
  3858. goto MemoryError;
  3859. pwszFormat = pwszTemp;
  3860. wcscat(pwszFormat, wszReason);
  3861. wcscat(pwszFormat, wszCOMMA);
  3862. }
  3863. if(pInfo->pbData[0] & CRL_REASON_CESSATION_OF_OPERATION_FLAG )
  3864. {
  3865. if(!LoadStringU(hFrmtFuncInst, IDS_CESSATION_OF_OPERATION, wszReason, CRL_REASON_SIZE))
  3866. goto LoadStringError;
  3867. #if (0) // DSIE: Bug 27436
  3868. pwszFormat=(LPWSTR)realloc(pwszFormat,
  3869. sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszReason)+1+wcslen(wszCOMMA)));
  3870. if(NULL==pwszFormat)
  3871. goto MemoryError;
  3872. #endif
  3873. pwszTemp=(LPWSTR)realloc(pwszFormat,
  3874. sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszReason)+1+wcslen(wszCOMMA)));
  3875. if(NULL==pwszTemp)
  3876. goto MemoryError;
  3877. pwszFormat = pwszTemp;
  3878. wcscat(pwszFormat, wszReason);
  3879. wcscat(pwszFormat, wszCOMMA);
  3880. }
  3881. if(pInfo->pbData[0] & CRL_REASON_CERTIFICATE_HOLD_FLAG )
  3882. {
  3883. if(!LoadStringU(hFrmtFuncInst, IDS_CERTIFICATE_HOLD, wszReason, CRL_REASON_SIZE))
  3884. goto LoadStringError;
  3885. #if (0) // DSIE: Bug 27436
  3886. pwszFormat=(LPWSTR)realloc(pwszFormat,
  3887. sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszReason)+1+wcslen(wszCOMMA)));
  3888. if(NULL==pwszFormat)
  3889. goto MemoryError;
  3890. #endif
  3891. pwszTemp=(LPWSTR)realloc(pwszFormat,
  3892. sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszReason)+1+wcslen(wszCOMMA)));
  3893. if(NULL==pwszTemp)
  3894. goto MemoryError;
  3895. pwszFormat = pwszTemp;
  3896. wcscat(pwszFormat, wszReason);
  3897. wcscat(pwszFormat, wszCOMMA);
  3898. }
  3899. if(0==wcslen(pwszFormat))
  3900. {
  3901. #if (0) // DSIE: Bug 27436
  3902. pwszFormat=(LPWSTR)realloc(pwszFormat, sizeof(WCHAR) * (UNKNOWN_CRL_REASON_SIZE+1));
  3903. #endif
  3904. pwszTemp=(LPWSTR)realloc(pwszFormat, sizeof(WCHAR) * (UNKNOWN_CRL_REASON_SIZE+1));
  3905. if(NULL==pwszTemp)
  3906. goto MemoryError;
  3907. pwszFormat = pwszTemp;
  3908. if(!LoadStringU(hFrmtFuncInst, IDS_UNKNOWN_CRL_REASON, pwszFormat,
  3909. UNKNOWN_CRL_REASON_SIZE))
  3910. goto LoadStringError;
  3911. }
  3912. else
  3913. {
  3914. //get rid of the last comma
  3915. *(pwszFormat+wcslen(pwszFormat)-wcslen(wszCOMMA))=L'\0';
  3916. }
  3917. //get the Hex dump of the Key Usage
  3918. cbNeeded=0;
  3919. if(!FormatBytesToHex(
  3920. dwCertEncodingType,
  3921. dwFormatType,
  3922. dwFormatStrType,
  3923. pFormatStruct,
  3924. lpszStructType,
  3925. pInfo->pbData,
  3926. pInfo->cbData,
  3927. NULL,
  3928. &cbNeeded))
  3929. goto FormatBytesToHexError;
  3930. pwszByte=(LPWSTR)malloc(cbNeeded);
  3931. if(NULL==pwszByte)
  3932. goto MemoryError;
  3933. if(!FormatBytesToHex(
  3934. dwCertEncodingType,
  3935. dwFormatType,
  3936. dwFormatStrType,
  3937. pFormatStruct,
  3938. lpszStructType,
  3939. pInfo->pbData,
  3940. pInfo->cbData,
  3941. pwszByte,
  3942. &cbNeeded))
  3943. goto FormatBytesToHexError;
  3944. //convert the WSZ
  3945. if(!FormatMessageUnicode(ppwszFormat, IDS_BIT_BLOB, pwszFormat,
  3946. pwszByte))
  3947. goto FormatMsgError;
  3948. fResult=TRUE;
  3949. CommonReturn:
  3950. if(pwszFormat)
  3951. free(pwszFormat);
  3952. if(pwszByte)
  3953. free(pwszByte);
  3954. return fResult;
  3955. ErrorReturn:
  3956. if(*ppwszFormat)
  3957. {
  3958. LocalFree((HLOCAL)(*ppwszFormat));
  3959. *ppwszFormat=NULL;
  3960. }
  3961. fResult=FALSE;
  3962. goto CommonReturn;
  3963. TRACE_ERROR(LoadStringError);
  3964. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  3965. TRACE_ERROR(FormatBytesToHexError);
  3966. TRACE_ERROR(FormatMsgError);
  3967. }
  3968. //--------------------------------------------------------------------------
  3969. //
  3970. // FormatCRLDistPoints: X509_CRL_DIST_POINTS
  3971. // szOID_CRL_DIST_POINTS
  3972. // szOID_FRESHEST_CRL
  3973. // szOID_CRL_SELF_CDP
  3974. //--------------------------------------------------------------------------
  3975. static BOOL
  3976. WINAPI
  3977. FormatCRLDistPoints(
  3978. DWORD dwCertEncodingType,
  3979. DWORD dwFormatType,
  3980. DWORD dwFormatStrType,
  3981. void *pFormatStruct,
  3982. LPCSTR lpszStructType,
  3983. const BYTE *pbEncoded,
  3984. DWORD cbEncoded,
  3985. void *pbFormat,
  3986. DWORD *pcbFormat)
  3987. {
  3988. LPWSTR pwszFormat=NULL;
  3989. LPWSTR pwsz=NULL;
  3990. LPWSTR pwszEntryFormat=NULL;
  3991. LPWSTR pwszEntryTagFormat=NULL;
  3992. LPWSTR pwszPointName=NULL;
  3993. LPWSTR pwszNameFormat=NULL;
  3994. LPWSTR pwszCRLReason=NULL;
  3995. LPWSTR pwszReasonFormat=NULL;
  3996. LPWSTR pwszCRLIssuer=NULL;
  3997. LPWSTR pwszIssuerFormat=NULL;
  3998. PCRL_DIST_POINTS_INFO pInfo=NULL;
  3999. DWORD cbNeeded=0;
  4000. DWORD dwIndex=0;
  4001. BOOL fResult=FALSE;
  4002. UINT ids=0;
  4003. LPWSTR pwszTemp;
  4004. LPCSTR pszOID;
  4005. //check for input parameters
  4006. if((NULL==pbEncoded&& cbEncoded!=0) ||
  4007. (NULL==pcbFormat))
  4008. goto InvalidArg;
  4009. if(cbEncoded==0)
  4010. {
  4011. *pcbFormat=0;
  4012. goto InvalidArg;
  4013. }
  4014. //DSIE: Cert server encodes szOID_CRL_SEL_CDP using szOID_CRL_DIST_POINTS,
  4015. // so we need to change the lpszStructType for decoding.
  4016. if (0 == strcmp(lpszStructType, szOID_CRL_SELF_CDP))
  4017. {
  4018. pszOID = szOID_CRL_DIST_POINTS;
  4019. }
  4020. else
  4021. {
  4022. pszOID = lpszStructType;
  4023. }
  4024. if (!DecodeGenericBLOB(dwCertEncodingType, pszOID, //lpszStructType,
  4025. pbEncoded, cbEncoded, (void **)&pInfo))
  4026. goto DecodeGenericError;
  4027. pwsz=(LPWSTR)malloc(sizeof(WCHAR));
  4028. if(NULL==pwsz)
  4029. goto MemoryError;
  4030. *pwsz=L'\0';
  4031. for(dwIndex=0; dwIndex<pInfo->cDistPoint; dwIndex++)
  4032. {
  4033. //format distribution name
  4034. if(0!=pInfo->rgDistPoint[dwIndex].DistPointName.dwDistPointNameChoice)
  4035. {
  4036. if(!FormatDistPointName(
  4037. dwCertEncodingType,
  4038. dwFormatType,
  4039. dwFormatStrType,
  4040. pFormatStruct,
  4041. &(pInfo->rgDistPoint[dwIndex].DistPointName),
  4042. &pwszPointName))
  4043. goto FormatDistPointNameError;
  4044. //decide between single line and mulitple line format
  4045. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  4046. ids=IDS_CRL_DIST_NAME_MULTI;
  4047. else
  4048. ids=IDS_CRL_DIST_NAME;
  4049. if(!FormatMessageUnicode(&pwszNameFormat, ids,pwszPointName))
  4050. goto FormatMsgError;
  4051. }
  4052. //format the CRL reason
  4053. if(0!=pInfo->rgDistPoint[dwIndex].ReasonFlags.cbData)
  4054. {
  4055. if(!FormatCRLReason(dwCertEncodingType,
  4056. dwFormatType,
  4057. dwFormatStrType,
  4058. pFormatStruct,
  4059. lpszStructType,
  4060. &(pInfo->rgDistPoint[dwIndex].ReasonFlags),
  4061. &pwszCRLReason))
  4062. goto FormatCRLReasonError;
  4063. //decide between single line and mulitple line format
  4064. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  4065. ids=IDS_CRL_DIST_REASON_MULTI;
  4066. else
  4067. ids=IDS_CRL_DIST_REASON;
  4068. if(!FormatMessageUnicode(&pwszReasonFormat, ids ,pwszCRLReason))
  4069. goto FormatMsgError;
  4070. }
  4071. //format the Issuer
  4072. if(0!=pInfo->rgDistPoint[dwIndex].CRLIssuer.cAltEntry)
  4073. {
  4074. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  4075. ids=IDS_TWO_TABS;
  4076. else
  4077. ids=0;
  4078. cbNeeded=0;
  4079. if(!FormatAltNameInfo(dwCertEncodingType,
  4080. dwFormatType,
  4081. dwFormatStrType,
  4082. pFormatStruct,
  4083. ids,
  4084. FALSE,
  4085. &(pInfo->rgDistPoint[dwIndex].CRLIssuer),
  4086. NULL,
  4087. &cbNeeded))
  4088. goto FormatAltNameError;
  4089. pwszCRLIssuer=(LPWSTR)malloc(cbNeeded);
  4090. if(NULL==pwszCRLIssuer)
  4091. goto MemoryError;
  4092. if(!FormatAltNameInfo(dwCertEncodingType,
  4093. dwFormatType,
  4094. dwFormatStrType,
  4095. pFormatStruct,
  4096. ids,
  4097. FALSE,
  4098. &(pInfo->rgDistPoint[dwIndex].CRLIssuer),
  4099. pwszCRLIssuer,
  4100. &cbNeeded))
  4101. goto FormatAltNameError;
  4102. //decide between single line and mulitple line format
  4103. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  4104. ids=IDS_CRL_DIST_ISSUER_MULTI;
  4105. else
  4106. ids=IDS_CRL_DIST_ISSUER;
  4107. if(!FormatMessageUnicode(&pwszIssuerFormat,ids,pwszCRLIssuer))
  4108. goto FormatMsgError;
  4109. }
  4110. cbNeeded=0;
  4111. if(pwszNameFormat)
  4112. cbNeeded+=wcslen(pwszNameFormat);
  4113. if(pwszReasonFormat)
  4114. cbNeeded+=wcslen(pwszReasonFormat);
  4115. if(pwszIssuerFormat)
  4116. cbNeeded+=wcslen(pwszIssuerFormat);
  4117. if(0!=cbNeeded)
  4118. {
  4119. //add ", " between each element for single line format
  4120. if(0== (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
  4121. {
  4122. if(0!=wcslen(pwsz))
  4123. wcscat(pwsz, wszCOMMA);
  4124. }
  4125. //strcat all the information, including the COMMA
  4126. cbNeeded += wcslen(wszCOMMA)*2;
  4127. pwszEntryFormat=(LPWSTR)malloc(sizeof(WCHAR) * (cbNeeded+1));
  4128. if(NULL==pwszEntryFormat)
  4129. goto MemoryError;
  4130. *pwszEntryFormat=L'\0';
  4131. //strcat all three fields one at a time
  4132. if(pwszNameFormat)
  4133. wcscat(pwszEntryFormat, pwszNameFormat);
  4134. if(pwszReasonFormat)
  4135. {
  4136. if(0!=wcslen(pwszEntryFormat))
  4137. {
  4138. if(0==(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
  4139. wcscat(pwszEntryFormat, wszCOMMA);
  4140. }
  4141. wcscat(pwszEntryFormat, pwszReasonFormat);
  4142. }
  4143. if(pwszIssuerFormat)
  4144. {
  4145. if(0!=wcslen(pwszEntryFormat))
  4146. {
  4147. if(0==(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
  4148. wcscat(pwszEntryFormat, wszCOMMA);
  4149. }
  4150. wcscat(pwszEntryFormat, pwszIssuerFormat);
  4151. }
  4152. //format the entry
  4153. //decide between single line and mulitple line format
  4154. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  4155. //
  4156. // DSIE: Load appropriate format string.
  4157. //
  4158. if (0 == strcmp(lpszStructType, szOID_FRESHEST_CRL))
  4159. ids=IDS_FRESHEST_CRL_MULTI;
  4160. else if (0 == strcmp(lpszStructType, szOID_CRL_SELF_CDP))
  4161. ids=IDS_CRL_SELF_CDP_MULTI;
  4162. else
  4163. ids=IDS_CRL_DIST_ENTRY_MULTI;
  4164. else
  4165. if (0 == strcmp(lpszStructType, szOID_FRESHEST_CRL))
  4166. ids=IDS_FRESHEST_CRL;
  4167. else if (0 == strcmp(lpszStructType, szOID_CRL_SELF_CDP))
  4168. ids=IDS_CRL_SELF_CDP;
  4169. else
  4170. ids=IDS_CRL_DIST_ENTRY;
  4171. if(!FormatMessageUnicode(&pwszEntryTagFormat, ids, dwIndex+1,
  4172. pwszEntryFormat))
  4173. goto FormatMsgError;
  4174. //strcat the entry
  4175. #if (0) // DSIE: Bug 27436
  4176. pwsz=(LPWSTR)realloc(pwsz,
  4177. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszEntryTagFormat)+1));
  4178. if(NULL==pwsz)
  4179. goto MemoryError;
  4180. #endif
  4181. pwszTemp=(LPWSTR)realloc(pwsz,
  4182. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszEntryTagFormat)+1));
  4183. if(NULL==pwszTemp)
  4184. goto MemoryError;
  4185. pwsz = pwszTemp;
  4186. wcscat(pwsz, pwszEntryTagFormat);
  4187. //free memory
  4188. free(pwszEntryFormat);
  4189. pwszEntryFormat=NULL;
  4190. LocalFree(pwszEntryTagFormat);
  4191. pwszEntryTagFormat=NULL;
  4192. }
  4193. //free memory
  4194. if(pwszPointName)
  4195. {
  4196. LocalFree((HLOCAL)pwszPointName);
  4197. pwszPointName=NULL;
  4198. }
  4199. if(pwszCRLReason)
  4200. {
  4201. LocalFree((HLOCAL)(pwszCRLReason));
  4202. pwszCRLReason=NULL;
  4203. }
  4204. if(pwszCRLIssuer)
  4205. {
  4206. free(pwszCRLIssuer);
  4207. pwszCRLIssuer=NULL;
  4208. }
  4209. if(pwszNameFormat)
  4210. {
  4211. LocalFree((HLOCAL)pwszNameFormat);
  4212. pwszNameFormat=NULL;
  4213. }
  4214. if(pwszReasonFormat)
  4215. {
  4216. LocalFree((HLOCAL)pwszReasonFormat);
  4217. pwszReasonFormat=NULL;
  4218. }
  4219. if(pwszIssuerFormat)
  4220. {
  4221. LocalFree((HLOCAL)pwszIssuerFormat);
  4222. pwszIssuerFormat=NULL;
  4223. }
  4224. }
  4225. if(0==wcslen(pwsz))
  4226. {
  4227. //no data
  4228. pwszFormat=(LPWSTR)malloc(sizeof(WCHAR)*(NO_INFO_SIZE+1));
  4229. if(NULL==pwszFormat)
  4230. goto MemoryError;
  4231. if(!LoadStringU(hFrmtFuncInst,IDS_NO_INFO, pwszFormat, NO_INFO_SIZE))
  4232. goto LoadStringError;
  4233. }
  4234. else
  4235. {
  4236. pwszFormat=pwsz;
  4237. pwsz=NULL;
  4238. }
  4239. cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
  4240. //length only calculation
  4241. if(NULL==pbFormat)
  4242. {
  4243. *pcbFormat=cbNeeded;
  4244. fResult=TRUE;
  4245. goto CommonReturn;
  4246. }
  4247. if((*pcbFormat)<cbNeeded)
  4248. {
  4249. *pcbFormat=cbNeeded;
  4250. goto MoreDataError;
  4251. }
  4252. //copy the data
  4253. memcpy(pbFormat, pwszFormat, cbNeeded);
  4254. //copy the size
  4255. *pcbFormat=cbNeeded;
  4256. fResult=TRUE;
  4257. CommonReturn:
  4258. if(pwszEntryFormat)
  4259. free(pwszEntryFormat);
  4260. if(pwszEntryTagFormat)
  4261. LocalFree((HLOCAL)pwszEntryTagFormat);
  4262. //free memory
  4263. if(pwszPointName)
  4264. LocalFree((HLOCAL)pwszPointName);
  4265. if(pwszCRLReason)
  4266. LocalFree((HLOCAL)(pwszCRLReason));
  4267. if(pwszCRLIssuer)
  4268. free(pwszCRLIssuer);
  4269. if(pwszNameFormat)
  4270. LocalFree((HLOCAL)pwszNameFormat);
  4271. if(pwszReasonFormat)
  4272. LocalFree((HLOCAL)pwszReasonFormat);
  4273. if(pwszIssuerFormat)
  4274. LocalFree((HLOCAL)pwszIssuerFormat);
  4275. if(pwsz)
  4276. free(pwsz);
  4277. if(pwszFormat)
  4278. free(pwszFormat);
  4279. if(pInfo)
  4280. free(pInfo);
  4281. return fResult;
  4282. ErrorReturn:
  4283. fResult=FALSE;
  4284. goto CommonReturn;
  4285. SET_ERROR(InvalidArg, E_INVALIDARG);
  4286. TRACE_ERROR(DecodeGenericError);
  4287. TRACE_ERROR(LoadStringError);
  4288. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  4289. TRACE_ERROR(FormatMsgError);
  4290. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  4291. TRACE_ERROR(FormatDistPointNameError);
  4292. TRACE_ERROR(FormatCRLReasonError);
  4293. TRACE_ERROR(FormatAltNameError);
  4294. }
  4295. //--------------------------------------------------------------------------
  4296. //
  4297. // FormatCertPolicyID:
  4298. //
  4299. // Pre-condition: pCertPolicyID has to include the valid information.that is,
  4300. // cCertPolicyElementId can not be 0.
  4301. //--------------------------------------------------------------------------
  4302. BOOL FormatCertPolicyID(PCERT_POLICY_ID pCertPolicyID, LPWSTR *ppwszFormat)
  4303. {
  4304. BOOL fResult=FALSE;
  4305. LPSTR pszFormat=NULL;
  4306. DWORD dwIndex=0;
  4307. HRESULT hr=S_OK;
  4308. LPSTR pwszTemp;
  4309. *ppwszFormat=NULL;
  4310. if(0==pCertPolicyID->cCertPolicyElementId)
  4311. goto InvalidArg;
  4312. pszFormat=(LPSTR)malloc(sizeof(CHAR));
  4313. if(NULL==pszFormat)
  4314. goto MemoryError;
  4315. *pszFormat='\0';
  4316. for(dwIndex=0; dwIndex<pCertPolicyID->cCertPolicyElementId; dwIndex++)
  4317. {
  4318. #if (0) // DSIE: Bug 27436
  4319. pszFormat=(LPSTR)realloc(pszFormat, strlen(pszFormat)+
  4320. strlen(pCertPolicyID->rgpszCertPolicyElementId[dwIndex])+strlen(strCOMMA)+1);
  4321. if(NULL==pszFormat)
  4322. goto MemoryError;
  4323. #endif
  4324. pwszTemp=(LPSTR)realloc(pszFormat, strlen(pszFormat)+
  4325. strlen(pCertPolicyID->rgpszCertPolicyElementId[dwIndex])+strlen(strCOMMA)+1);
  4326. if(NULL==pwszTemp)
  4327. goto MemoryError;
  4328. pszFormat = pwszTemp;
  4329. strcat(pszFormat,pCertPolicyID->rgpszCertPolicyElementId[dwIndex]);
  4330. strcat(pszFormat, strCOMMA);
  4331. }
  4332. //get rid of the last COMMA
  4333. *(pszFormat+strlen(pszFormat)-strlen(strCOMMA))='\0';
  4334. //convert to WCHAR
  4335. if(S_OK!=(hr=SZtoWSZ(pszFormat, ppwszFormat)))
  4336. goto SZtoWSZError;
  4337. fResult=TRUE;
  4338. CommonReturn:
  4339. if(pszFormat)
  4340. free(pszFormat);
  4341. return fResult;
  4342. ErrorReturn:
  4343. if(*ppwszFormat)
  4344. {
  4345. free(*ppwszFormat);
  4346. *ppwszFormat=NULL;
  4347. }
  4348. fResult=FALSE;
  4349. goto CommonReturn;
  4350. SET_ERROR(InvalidArg, E_INVALIDARG);
  4351. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  4352. SET_ERROR_VAR(SZtoWSZError,hr);
  4353. }
  4354. //--------------------------------------------------------------------------
  4355. //
  4356. // FormatKeyRestriction: X509_KEY_USAGE_RESTRICTION
  4357. // szOID_KEY_USAGE_RESTRICTION
  4358. //
  4359. //
  4360. //--------------------------------------------------------------------------
  4361. static BOOL
  4362. WINAPI
  4363. FormatKeyRestriction(
  4364. DWORD dwCertEncodingType,
  4365. DWORD dwFormatType,
  4366. DWORD dwFormatStrType,
  4367. void *pFormatStruct,
  4368. LPCSTR lpszStructType,
  4369. const BYTE *pbEncoded,
  4370. DWORD cbEncoded,
  4371. void *pbFormat,
  4372. DWORD *pcbFormat)
  4373. {
  4374. LPWSTR pwszFormat=NULL;
  4375. LPWSTR pwsz=NULL;
  4376. PCERT_KEY_USAGE_RESTRICTION_INFO pInfo=NULL;
  4377. LPWSTR pwszPolicy=NULL;
  4378. LPWSTR pwszPolicyFormat=NULL;
  4379. LPWSTR pwszKeyUsage=NULL;
  4380. LPWSTR pwszKeyUsageFormat=NULL;
  4381. DWORD cbNeeded=0;
  4382. DWORD dwIndex=0;
  4383. BOOL fResult=FALSE;
  4384. UINT ids=0;
  4385. LPWSTR pwszTemp;
  4386. //check for input parameters
  4387. if((NULL==pbEncoded&& cbEncoded!=0) ||
  4388. (NULL==pcbFormat))
  4389. goto InvalidArg;
  4390. if(cbEncoded==0)
  4391. {
  4392. *pcbFormat=0;
  4393. goto InvalidArg;
  4394. }
  4395. if (!DecodeGenericBLOB(dwCertEncodingType,X509_KEY_USAGE_RESTRICTION,
  4396. pbEncoded,cbEncoded, (void **)&pInfo))
  4397. goto DecodeGenericError;
  4398. pwsz=(LPWSTR)malloc(sizeof(WCHAR));
  4399. if(NULL==pwsz)
  4400. goto MemoryError;
  4401. *pwsz=L'\0';
  4402. for(dwIndex=0; dwIndex<pInfo->cCertPolicyId; dwIndex++)
  4403. {
  4404. if(0!=((pInfo->rgCertPolicyId)[dwIndex].cCertPolicyElementId))
  4405. {
  4406. //concatecate the comma if not the 1st item
  4407. if(0!=wcslen(pwsz))
  4408. {
  4409. if(0== (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
  4410. wcscat(pwsz, wszCOMMA);
  4411. }
  4412. if(!FormatCertPolicyID(&((pInfo->rgCertPolicyId)[dwIndex]), &pwszPolicy))
  4413. goto FormatCertPolicyIDError;
  4414. //decide between single line and mulitple line format
  4415. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  4416. ids=IDS_KEY_RES_ID_MULTI;
  4417. else
  4418. ids=IDS_KEY_RES_ID;
  4419. if(!FormatMessageUnicode(&pwszPolicyFormat, ids,dwIndex+1,pwszPolicy))
  4420. goto FormatMsgError;
  4421. //allocate memory, including the ", "
  4422. #if (0) // DSIE: Bug 27436
  4423. pwsz=(LPWSTR)realloc(pwsz,
  4424. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszPolicyFormat)+1));
  4425. if(NULL==pwsz)
  4426. goto MemoryError;
  4427. #endif
  4428. pwszTemp=(LPWSTR)realloc(pwsz,
  4429. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszPolicyFormat)+1));
  4430. if(NULL==pwszTemp)
  4431. goto MemoryError;
  4432. pwsz = pwszTemp;
  4433. wcscat(pwsz, pwszPolicyFormat);
  4434. free(pwszPolicy);
  4435. pwszPolicy=NULL;
  4436. LocalFree((HLOCAL)pwszPolicyFormat);
  4437. pwszPolicyFormat=NULL;
  4438. }
  4439. }
  4440. //format the RestrictedKeyUsage
  4441. if(0!=pInfo->RestrictedKeyUsage.cbData)
  4442. {
  4443. //concatecate the comma if not the 1st item
  4444. if(0!=wcslen(pwsz))
  4445. {
  4446. if(0== (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
  4447. wcscat(pwsz, wszCOMMA);
  4448. }
  4449. cbNeeded=0;
  4450. if(!FormatKeyUsageBLOB(
  4451. dwCertEncodingType,
  4452. dwFormatType,
  4453. dwFormatStrType,
  4454. pFormatStruct,
  4455. lpszStructType,
  4456. &(pInfo->RestrictedKeyUsage),
  4457. NULL,
  4458. &cbNeeded))
  4459. goto FormatKeyUsageBLOBError;
  4460. pwszKeyUsage=(LPWSTR)malloc(cbNeeded);
  4461. if(NULL==pwszKeyUsage)
  4462. goto MemoryError;
  4463. if(!FormatKeyUsageBLOB(
  4464. dwCertEncodingType,
  4465. dwFormatType,
  4466. dwFormatStrType,
  4467. pFormatStruct,
  4468. lpszStructType,
  4469. &(pInfo->RestrictedKeyUsage),
  4470. pwszKeyUsage,
  4471. &cbNeeded))
  4472. goto FormatKeyUsageBLOBError;
  4473. //decide between single line and mulitple line format
  4474. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  4475. ids=IDS_KEY_RES_USAGE_MULTI;
  4476. else
  4477. ids=IDS_KEY_RES_USAGE;
  4478. //format the element string
  4479. if(!FormatMessageUnicode(&pwszKeyUsageFormat, ids, pwszKeyUsage))
  4480. goto FormatMsgError;
  4481. #if (0) // DSIE: Bug 27436
  4482. pwsz=(LPWSTR)realloc(pwsz,
  4483. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(pwszKeyUsageFormat)+1));
  4484. if(NULL==pwsz)
  4485. goto MemoryError;
  4486. #endif
  4487. pwszTemp=(LPWSTR)realloc(pwsz,
  4488. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(pwszKeyUsageFormat)+1));
  4489. if(NULL==pwszTemp)
  4490. goto MemoryError;
  4491. pwsz = pwszTemp;
  4492. wcscat(pwsz, pwszKeyUsageFormat);
  4493. }
  4494. if(0==wcslen(pwsz))
  4495. {
  4496. //no data
  4497. pwszFormat=(LPWSTR)malloc(sizeof(WCHAR)*(NO_INFO_SIZE+1));
  4498. if(NULL==pwszFormat)
  4499. goto MemoryError;
  4500. if(!LoadStringU(hFrmtFuncInst,IDS_NO_INFO, pwszFormat, NO_INFO_SIZE))
  4501. goto LoadStringError;
  4502. }
  4503. else
  4504. {
  4505. pwszFormat=pwsz;
  4506. pwsz=NULL;
  4507. }
  4508. cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
  4509. //length only calculation
  4510. if(NULL==pbFormat)
  4511. {
  4512. *pcbFormat=cbNeeded;
  4513. fResult=TRUE;
  4514. goto CommonReturn;
  4515. }
  4516. if((*pcbFormat)<cbNeeded)
  4517. {
  4518. *pcbFormat=cbNeeded;
  4519. goto MoreDataError;
  4520. }
  4521. //copy the data
  4522. memcpy(pbFormat, pwszFormat, cbNeeded);
  4523. //copy the size
  4524. *pcbFormat=cbNeeded;
  4525. fResult=TRUE;
  4526. CommonReturn:
  4527. if(pwszPolicy)
  4528. free(pwszPolicy);
  4529. if(pwszPolicyFormat)
  4530. LocalFree((HLOCAL)pwszPolicyFormat);
  4531. if(pwszKeyUsage)
  4532. free(pwszKeyUsage);
  4533. if(pwszKeyUsageFormat)
  4534. LocalFree((HLOCAL)pwszKeyUsageFormat);
  4535. if(pwszFormat)
  4536. free(pwszFormat);
  4537. if(pwsz)
  4538. free(pwsz);
  4539. if(pInfo)
  4540. free(pInfo);
  4541. return fResult;
  4542. ErrorReturn:
  4543. fResult=FALSE;
  4544. goto CommonReturn;
  4545. SET_ERROR(InvalidArg, E_INVALIDARG);
  4546. TRACE_ERROR(DecodeGenericError);
  4547. TRACE_ERROR(LoadStringError);
  4548. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  4549. TRACE_ERROR(FormatMsgError);
  4550. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  4551. TRACE_ERROR(FormatCertPolicyIDError);
  4552. TRACE_ERROR(FormatKeyUsageBLOBError);
  4553. }
  4554. //-----------------------------------------------------------------------
  4555. //
  4556. // FormatFileTime
  4557. //
  4558. // Pre-condition: pFileTime points to valid data
  4559. //
  4560. //------------------------------------------------------------------------
  4561. BOOL FormatFileTime(FILETIME *pFileTime,LPWSTR *ppwszFormat)
  4562. {
  4563. BOOL fResult;
  4564. int cch;
  4565. int cch2;
  4566. LPWSTR psz;
  4567. SYSTEMTIME st;
  4568. FILETIME localTime;
  4569. DWORD locale;
  4570. BOOL bRTLLocale;
  4571. DWORD dwFlags = DATE_LONGDATE;
  4572. // See if the user locale id is RTL (Arabic, Urdu, Farsi or Hebrew).
  4573. locale = GetUserDefaultLCID();
  4574. bRTLLocale = ((PRIMARYLANGID(LANGIDFROMLCID(locale)) == LANG_ARABIC) ||
  4575. (PRIMARYLANGID(LANGIDFROMLCID(locale)) == LANG_URDU) ||
  4576. (PRIMARYLANGID(LANGIDFROMLCID(locale)) == LANG_FARSI) ||
  4577. (PRIMARYLANGID(LANGIDFROMLCID(locale)) == LANG_HEBREW));
  4578. locale = MAKELCID( MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), SORT_DEFAULT) ;
  4579. if (bRTLLocale)
  4580. {
  4581. DWORD dwLayout;
  4582. if (GetProcessDefaultLayout(&dwLayout))
  4583. {
  4584. if (dwLayout & LAYOUT_RTL)
  4585. {
  4586. dwFlags |= DATE_RTLREADING;
  4587. }
  4588. else
  4589. {
  4590. dwFlags |= DATE_LTRREADING;
  4591. }
  4592. }
  4593. else
  4594. {
  4595. dwFlags |= DATE_LTRREADING;
  4596. }
  4597. }
  4598. if (!FileTimeToLocalFileTime(pFileTime, &localTime))
  4599. {
  4600. goto ToLocalTimeError;
  4601. }
  4602. if (!FileTimeToSystemTime(&localTime, &st))
  4603. {
  4604. //
  4605. // if the conversion to local time failed, then just use the original time
  4606. //
  4607. if (!FileTimeToSystemTime(pFileTime, &st))
  4608. {
  4609. goto ToSystemTimeError;
  4610. }
  4611. }
  4612. cch = (GetTimeFormatU(LOCALE_USER_DEFAULT, 0, &st, NULL, NULL, 0) +
  4613. GetDateFormatU(locale, dwFlags, &st, NULL, NULL, 0) + 5);
  4614. if (NULL == (psz = (LPWSTR) LocalAlloc(LPTR, (cch+5) * sizeof(WCHAR))))
  4615. {
  4616. goto OutOfMemoryError;
  4617. }
  4618. cch2 = GetDateFormatU(locale, dwFlags, &st, NULL, psz, cch);
  4619. psz[cch2-1] = ' ';
  4620. GetTimeFormatU(LOCALE_USER_DEFAULT, 0, &st, NULL, &psz[cch2], cch-cch2);
  4621. *ppwszFormat = psz;
  4622. fResult = TRUE;
  4623. CommonReturn:
  4624. return fResult;
  4625. ErrorReturn:
  4626. if(*ppwszFormat)
  4627. {
  4628. LocalFree((HLOCAL)(*ppwszFormat));
  4629. *ppwszFormat=NULL;
  4630. }
  4631. fResult=FALSE;
  4632. goto CommonReturn;
  4633. TRACE_ERROR(ToLocalTimeError);
  4634. TRACE_ERROR(ToSystemTimeError);
  4635. TRACE_ERROR(OutOfMemoryError);
  4636. }
  4637. //--------------------------------------------------------------------------
  4638. //
  4639. // FormatKeyAttributes: X509_KEY_ATTRIBUTES
  4640. // szOID_KEY_ATTRIBUTES
  4641. //--------------------------------------------------------------------------
  4642. static BOOL
  4643. WINAPI
  4644. FormatKeyAttributes(
  4645. DWORD dwCertEncodingType,
  4646. DWORD dwFormatType,
  4647. DWORD dwFormatStrType,
  4648. void *pFormatStruct,
  4649. LPCSTR lpszStructType,
  4650. const BYTE *pbEncoded,
  4651. DWORD cbEncoded,
  4652. void *pbFormat,
  4653. DWORD *pcbFormat)
  4654. {
  4655. LPWSTR pwszFormat=NULL;
  4656. LPWSTR pwsz=NULL;
  4657. LPWSTR pwszKeyIDFormat=NULL;
  4658. LPWSTR pwszKeyID=NULL;
  4659. LPWSTR pwszKeyUsageFormat=NULL;
  4660. LPWSTR pwszKeyUsage=NULL;
  4661. LPWSTR pwszKeyBeforeFormat=NULL;
  4662. LPWSTR pwszKeyBefore=NULL;
  4663. LPWSTR pwszKeyAfterFormat=NULL;
  4664. LPWSTR pwszKeyAfter=NULL;
  4665. PCERT_KEY_ATTRIBUTES_INFO pInfo=NULL;
  4666. DWORD cbNeeded=0;
  4667. BOOL fResult=FALSE;
  4668. UINT ids=0;
  4669. LPWSTR pwszTemp;
  4670. //check for input parameters
  4671. if((NULL==pbEncoded&& cbEncoded!=0) ||
  4672. (NULL==pcbFormat))
  4673. goto InvalidArg;
  4674. if(cbEncoded==0)
  4675. {
  4676. *pcbFormat=0;
  4677. goto InvalidArg;
  4678. }
  4679. if (!DecodeGenericBLOB(dwCertEncodingType,X509_KEY_ATTRIBUTES,
  4680. pbEncoded,cbEncoded, (void **)&pInfo))
  4681. goto DecodeGenericError;
  4682. pwsz=(LPWSTR)malloc(sizeof(WCHAR));
  4683. if(NULL==pwsz)
  4684. goto MemoryError;
  4685. *pwsz=L'\0';
  4686. if(0!=pInfo->KeyId.cbData)
  4687. {
  4688. cbNeeded=0;
  4689. if(!FormatBytesToHex(
  4690. dwCertEncodingType,
  4691. dwFormatType,
  4692. dwFormatStrType,
  4693. pFormatStruct,
  4694. lpszStructType,
  4695. pInfo->KeyId.pbData,
  4696. pInfo->KeyId.cbData,
  4697. NULL,
  4698. &cbNeeded))
  4699. goto FormatBytesToHexError;
  4700. pwszKeyID=(LPWSTR)malloc(cbNeeded);
  4701. if(NULL==pwszKeyID)
  4702. goto MemoryError;
  4703. if(!FormatBytesToHex(
  4704. dwCertEncodingType,
  4705. dwFormatType,
  4706. dwFormatStrType,
  4707. pFormatStruct,
  4708. lpszStructType,
  4709. pInfo->KeyId.pbData,
  4710. pInfo->KeyId.cbData,
  4711. pwszKeyID,
  4712. &cbNeeded))
  4713. goto FormatBytesToHexError;
  4714. //format the element string
  4715. //decide between single line and mulitple line format
  4716. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  4717. ids=IDS_KEY_ATTR_ID_MULTI;
  4718. else
  4719. ids=IDS_KEY_ATTR_ID;
  4720. if(!FormatMessageUnicode(&pwszKeyIDFormat, ids, pwszKeyID))
  4721. goto FormatMsgError;
  4722. #if (0) // DSIE: Bug 27436
  4723. pwsz=(LPWSTR)realloc(pwsz,
  4724. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszKeyIDFormat)+1));
  4725. if(NULL==pwsz)
  4726. goto MemoryError;
  4727. #endif
  4728. pwszTemp=(LPWSTR)realloc(pwsz,
  4729. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszKeyIDFormat)+1));
  4730. if(NULL==pwszTemp)
  4731. goto MemoryError;
  4732. pwsz = pwszTemp;
  4733. wcscat(pwsz, pwszKeyIDFormat);
  4734. }
  4735. //check the no data situation
  4736. if(0!=pInfo->IntendedKeyUsage.cbData)
  4737. {
  4738. //strcat a ", " symbol for signle line format
  4739. if(0== (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
  4740. {
  4741. if(0!=wcslen(pwsz))
  4742. wcscat(pwsz, wszCOMMA);
  4743. }
  4744. cbNeeded=0;
  4745. if(!FormatKeyUsageBLOB(
  4746. dwCertEncodingType,
  4747. dwFormatType,
  4748. dwFormatStrType,
  4749. pFormatStruct,
  4750. lpszStructType,
  4751. &(pInfo->IntendedKeyUsage),
  4752. NULL,
  4753. &cbNeeded))
  4754. goto FormatKeyUsageBLOBError;
  4755. pwszKeyUsage=(LPWSTR)malloc(cbNeeded);
  4756. if(NULL==pwszKeyUsage)
  4757. goto MemoryError;
  4758. if(!FormatKeyUsageBLOB(
  4759. dwCertEncodingType,
  4760. dwFormatType,
  4761. dwFormatStrType,
  4762. pFormatStruct,
  4763. lpszStructType,
  4764. &(pInfo->IntendedKeyUsage),
  4765. pwszKeyUsage,
  4766. &cbNeeded))
  4767. goto FormatKeyUsageBLOBError;
  4768. //format the element string
  4769. //decide between single line and mulitple line format
  4770. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  4771. ids=IDS_KEY_ATTR_USAGE_MULTI;
  4772. else
  4773. ids=IDS_KEY_ATTR_USAGE;
  4774. if(!FormatMessageUnicode(&pwszKeyUsageFormat, ids, pwszKeyUsage))
  4775. goto FormatMsgError;
  4776. #if (0) // DSIE: Bug 27436
  4777. pwsz=(LPWSTR)realloc(pwsz,
  4778. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszKeyUsageFormat)+1));
  4779. if(NULL==pwsz)
  4780. goto MemoryError;
  4781. #endif
  4782. pwszTemp=(LPWSTR)realloc(pwsz,
  4783. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszKeyUsageFormat)+1));
  4784. if(NULL==pwszTemp)
  4785. goto MemoryError;
  4786. pwsz = pwszTemp;
  4787. wcscat(pwsz, pwszKeyUsageFormat);
  4788. }
  4789. if(NULL!=pInfo->pPrivateKeyUsagePeriod)
  4790. {
  4791. //format only if there is some information
  4792. if(!((0==pInfo->pPrivateKeyUsagePeriod->NotBefore.dwHighDateTime)
  4793. &&(0==pInfo->pPrivateKeyUsagePeriod->NotBefore.dwLowDateTime)))
  4794. {
  4795. //strcat a ", " symbol for signle line format
  4796. if(0== (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
  4797. {
  4798. if(0!=wcslen(pwsz))
  4799. wcscat(pwsz, wszCOMMA);
  4800. }
  4801. if(!FormatFileTime(&(pInfo->pPrivateKeyUsagePeriod->NotBefore),
  4802. &pwszKeyBefore))
  4803. goto FormatFileTimeError;
  4804. //format the element string
  4805. //decide between single line and mulitple line format
  4806. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  4807. ids=IDS_KEY_ATTR_BEFORE_MULTI;
  4808. else
  4809. ids=IDS_KEY_ATTR_BEFORE;
  4810. if(!FormatMessageUnicode(&pwszKeyBeforeFormat, ids,
  4811. pwszKeyBefore))
  4812. goto FormatMsgError;
  4813. #if (0) // DSIE: Bug 27436
  4814. pwsz=(LPWSTR)realloc(pwsz,
  4815. sizeof(WCHAR)*(wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszKeyBeforeFormat)+1));
  4816. if(NULL==pwsz)
  4817. goto MemoryError;
  4818. #endif
  4819. pwszTemp=(LPWSTR)realloc(pwsz,
  4820. sizeof(WCHAR)*(wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszKeyBeforeFormat)+1));
  4821. if(NULL==pwszTemp)
  4822. goto MemoryError;
  4823. pwsz = pwszTemp;
  4824. wcscat(pwsz, pwszKeyBeforeFormat);
  4825. }
  4826. if(!((0==pInfo->pPrivateKeyUsagePeriod->NotAfter.dwHighDateTime)
  4827. &&(0==pInfo->pPrivateKeyUsagePeriod->NotAfter.dwLowDateTime)))
  4828. {
  4829. //strcat a ", " symbol for signle line format
  4830. if(0== (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
  4831. {
  4832. if(0!=wcslen(pwsz))
  4833. wcscat(pwsz, wszCOMMA);
  4834. }
  4835. if(!FormatFileTime(&(pInfo->pPrivateKeyUsagePeriod->NotAfter),
  4836. &pwszKeyAfter))
  4837. goto FormatFileTimeError;
  4838. //format the element string
  4839. //decide between single line and mulitple line format
  4840. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  4841. ids=IDS_KEY_ATTR_AFTER_MULTI;
  4842. else
  4843. ids=IDS_KEY_ATTR_AFTER;
  4844. if(!FormatMessageUnicode(&pwszKeyAfterFormat, ids,
  4845. pwszKeyAfter))
  4846. goto FormatMsgError;
  4847. #if (0) // DSIE: Bug 27436
  4848. pwsz=(LPWSTR)realloc(pwsz,
  4849. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszKeyAfterFormat)+1));
  4850. if(NULL==pwsz)
  4851. goto MemoryError;
  4852. #endif
  4853. pwszTemp=(LPWSTR)realloc(pwsz,
  4854. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszKeyAfterFormat)+1));
  4855. if(NULL==pwszTemp)
  4856. goto MemoryError;
  4857. pwsz = pwszTemp;
  4858. wcscat(pwsz, pwszKeyAfterFormat);
  4859. }
  4860. }
  4861. if(0==wcslen(pwsz))
  4862. {
  4863. pwszFormat=(LPWSTR)malloc(sizeof(WCHAR)*(NO_INFO_SIZE+1));
  4864. if(NULL==pwszFormat)
  4865. goto MemoryError;
  4866. if(!LoadStringU(hFrmtFuncInst,IDS_NO_INFO, pwszFormat,NO_INFO_SIZE))
  4867. goto LoadStringError;
  4868. }
  4869. else
  4870. {
  4871. pwszFormat=pwsz;
  4872. pwsz=NULL;
  4873. }
  4874. cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
  4875. //length only calculation
  4876. if(NULL==pbFormat)
  4877. {
  4878. *pcbFormat=cbNeeded;
  4879. fResult=TRUE;
  4880. goto CommonReturn;
  4881. }
  4882. if((*pcbFormat)<cbNeeded)
  4883. {
  4884. *pcbFormat=cbNeeded;
  4885. goto MoreDataError;
  4886. }
  4887. //copy the data
  4888. memcpy(pbFormat, pwszFormat, cbNeeded);
  4889. //copy the size
  4890. *pcbFormat=cbNeeded;
  4891. fResult=TRUE;
  4892. CommonReturn:
  4893. if(pwszKeyIDFormat)
  4894. LocalFree((HLOCAL)pwszKeyIDFormat);
  4895. if(pwszKeyID)
  4896. free(pwszKeyID);
  4897. if(pwszKeyUsageFormat)
  4898. LocalFree((HLOCAL)pwszKeyUsageFormat);
  4899. if(pwszKeyUsage)
  4900. free(pwszKeyUsage);
  4901. if(pwszKeyBeforeFormat)
  4902. LocalFree((HLOCAL)pwszKeyBeforeFormat);
  4903. if(pwszKeyBefore)
  4904. LocalFree((HLOCAL)pwszKeyBefore);
  4905. if(pwszKeyAfterFormat)
  4906. LocalFree((HLOCAL)pwszKeyAfterFormat);
  4907. if(pwszKeyAfter)
  4908. LocalFree((HLOCAL)pwszKeyAfter);
  4909. if(pwszFormat)
  4910. free(pwszFormat);
  4911. if(pwsz)
  4912. free(pwsz);
  4913. if(pInfo)
  4914. free(pInfo);
  4915. return fResult;
  4916. ErrorReturn:
  4917. fResult=FALSE;
  4918. goto CommonReturn;
  4919. SET_ERROR(InvalidArg, E_INVALIDARG);
  4920. TRACE_ERROR(DecodeGenericError);
  4921. TRACE_ERROR(LoadStringError);
  4922. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  4923. TRACE_ERROR(FormatKeyUsageBLOBError);
  4924. TRACE_ERROR(FormatFileTimeError);
  4925. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  4926. TRACE_ERROR(FormatBytesToHexError);
  4927. TRACE_ERROR(FormatMsgError);
  4928. }
  4929. //--------------------------------------------------------------------------
  4930. //
  4931. // FormatAuthortiyInfoAccess: X509_AUTHORITY_INFO_ACCESS
  4932. // szOID_AUTHORITY_INFO_ACCESS
  4933. //--------------------------------------------------------------------------
  4934. static BOOL
  4935. WINAPI
  4936. FormatAuthortiyInfoAccess(
  4937. DWORD dwCertEncodingType,
  4938. DWORD dwFormatType,
  4939. DWORD dwFormatStrType,
  4940. void *pFormatStruct,
  4941. LPCSTR lpszStructType,
  4942. const BYTE *pbEncoded,
  4943. DWORD cbEncoded,
  4944. void *pbFormat,
  4945. DWORD *pcbFormat)
  4946. {
  4947. BOOL fMethodAllocated=FALSE;
  4948. WCHAR wszNoInfo[NO_INFO_SIZE];
  4949. WCHAR wszUnknownAccess[UNKNOWN_ACCESS_METHOD_SIZE];
  4950. PCCRYPT_OID_INFO pOIDInfo=NULL;
  4951. CERT_ALT_NAME_INFO CertAltNameInfo;
  4952. LPWSTR pwszFormat=NULL;
  4953. LPWSTR pwsz=NULL;
  4954. LPWSTR pwszMethod=NULL;
  4955. LPWSTR pwszAltName=NULL;
  4956. LPWSTR pwszEntryFormat=NULL;
  4957. PCERT_AUTHORITY_INFO_ACCESS pInfo=NULL;
  4958. DWORD dwIndex=0;
  4959. DWORD cbNeeded=0;
  4960. BOOL fResult=FALSE;
  4961. UINT ids=0;
  4962. LPWSTR pwszTemp;
  4963. //check for input parameters
  4964. if((NULL==pbEncoded&& cbEncoded!=0) ||
  4965. (NULL==pcbFormat))
  4966. goto InvalidArg;
  4967. if(cbEncoded==0)
  4968. {
  4969. *pcbFormat=0;
  4970. goto InvalidArg;
  4971. }
  4972. if (!DecodeGenericBLOB(dwCertEncodingType,X509_AUTHORITY_INFO_ACCESS,
  4973. pbEncoded,cbEncoded, (void **)&pInfo))
  4974. goto DecodeGenericError;
  4975. if(0==pInfo->cAccDescr)
  4976. {
  4977. //load the string "Info Not Available"
  4978. if(!LoadStringU(hFrmtFuncInst,IDS_NO_INFO, wszNoInfo, sizeof(wszNoInfo)/sizeof(wszNoInfo[0])))
  4979. goto LoadStringError;
  4980. pwszFormat=wszNoInfo;
  4981. }
  4982. else
  4983. {
  4984. pwsz=(LPWSTR)malloc(sizeof(WCHAR));
  4985. if(NULL==pwsz)
  4986. goto MemoryError;
  4987. *pwsz=L'\0';
  4988. //load the string "Unknown Access Method:
  4989. if(!LoadStringU(hFrmtFuncInst,IDS_UNKNOWN_ACCESS_METHOD, wszUnknownAccess,
  4990. sizeof(wszUnknownAccess)/sizeof(wszUnknownAccess[0])))
  4991. goto LoadStringError;
  4992. for(dwIndex=0; dwIndex < pInfo->cAccDescr; dwIndex++)
  4993. {
  4994. fMethodAllocated=FALSE;
  4995. //need a ", " between each element for single line format
  4996. if(0!=wcslen(pwsz))
  4997. {
  4998. if(0==(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) )
  4999. wcscat(pwsz, wszCOMMA);
  5000. }
  5001. //get the name of the access method
  5002. if(pInfo->rgAccDescr[dwIndex].pszAccessMethod)
  5003. {
  5004. pOIDInfo=CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
  5005. (void *)(pInfo->rgAccDescr[dwIndex].pszAccessMethod),
  5006. CRYPT_EXT_OR_ATTR_OID_GROUP_ID);
  5007. //get the access method OID
  5008. if(pOIDInfo)
  5009. {
  5010. //allocate memory, including the NULL terminator
  5011. pwszMethod=(LPWSTR)malloc((wcslen(pOIDInfo->pwszName)+1)*
  5012. sizeof(WCHAR));
  5013. if(NULL==pwszMethod)
  5014. goto MemoryError;
  5015. fMethodAllocated=TRUE;
  5016. wcscpy(pwszMethod,pOIDInfo->pwszName);
  5017. }else
  5018. pwszMethod=wszUnknownAccess;
  5019. }
  5020. memset(&CertAltNameInfo, 0, sizeof(CERT_ALT_NAME_INFO));
  5021. CertAltNameInfo.cAltEntry=1;
  5022. CertAltNameInfo.rgAltEntry=&(pInfo->rgAccDescr[dwIndex].AccessLocation);
  5023. //need to tell if it is for multi line format. We need two \t\t
  5024. //in front of each alt name entry
  5025. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  5026. ids=IDS_TWO_TABS;
  5027. else
  5028. ids=0;
  5029. //get the alternative name entry
  5030. cbNeeded=0;
  5031. if(!FormatAltNameInfo(dwCertEncodingType,
  5032. dwFormatType,
  5033. dwFormatStrType,
  5034. pFormatStruct,
  5035. ids,
  5036. FALSE,
  5037. &CertAltNameInfo,
  5038. NULL,
  5039. &cbNeeded))
  5040. goto FormatAltNameError;
  5041. pwszAltName=(LPWSTR)malloc(cbNeeded);
  5042. if(NULL==pwszAltName)
  5043. goto MemoryError;
  5044. if(!FormatAltNameInfo(dwCertEncodingType,
  5045. dwFormatType,
  5046. dwFormatStrType,
  5047. pFormatStruct,
  5048. ids,
  5049. FALSE,
  5050. &CertAltNameInfo,
  5051. pwszAltName,
  5052. &cbNeeded))
  5053. goto FormatAltNameError;
  5054. //format the entry
  5055. if(pInfo->rgAccDescr[dwIndex].pszAccessMethod)
  5056. {
  5057. //decide between single line and mulitple line format
  5058. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  5059. ids=IDS_AUTHORITY_ACCESS_INFO_MULTI;
  5060. else
  5061. ids=IDS_AUTHORITY_ACCESS_INFO;
  5062. if(!FormatMessageUnicode(&pwszEntryFormat, ids,
  5063. dwIndex+1, pwszMethod, pInfo->rgAccDescr[dwIndex].pszAccessMethod,
  5064. pwszAltName))
  5065. goto FormatMsgError;
  5066. }
  5067. else
  5068. {
  5069. //decide between single line and mulitple line format
  5070. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  5071. ids=IDS_AUTHORITY_ACCESS_NO_METHOD_MULTI;
  5072. else
  5073. ids=IDS_AUTHORITY_ACCESS_NO_METHOD;
  5074. if(!FormatMessageUnicode(&pwszEntryFormat, ids, dwIndex+1, pwszAltName))
  5075. goto FormatMsgError;
  5076. }
  5077. //reallocat the memory. Leave space for szComma
  5078. #if (0) // DSIE: Bug 27436
  5079. pwsz=(LPWSTR)realloc(pwsz,
  5080. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(pwszEntryFormat)+
  5081. wcslen(wszCOMMA)+1));
  5082. if(NULL==pwsz)
  5083. goto MemoryError;
  5084. #endif
  5085. pwszTemp=(LPWSTR)realloc(pwsz,
  5086. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(pwszEntryFormat)+
  5087. wcslen(wszCOMMA)+1));
  5088. if(NULL==pwszTemp)
  5089. goto MemoryError;
  5090. pwsz = pwszTemp;
  5091. wcscat(pwsz, pwszEntryFormat);
  5092. //free memory
  5093. LocalFree((HLOCAL)pwszEntryFormat);
  5094. pwszEntryFormat=NULL;
  5095. free(pwszAltName);
  5096. pwszAltName=NULL;
  5097. if(TRUE==fMethodAllocated)
  5098. free(pwszMethod);
  5099. pwszMethod=NULL;
  5100. }
  5101. //convert to WCHAR
  5102. pwszFormat=pwsz;
  5103. }
  5104. cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
  5105. //length only calculation
  5106. if(NULL==pbFormat)
  5107. {
  5108. *pcbFormat=cbNeeded;
  5109. fResult=TRUE;
  5110. goto CommonReturn;
  5111. }
  5112. if((*pcbFormat)<cbNeeded)
  5113. {
  5114. *pcbFormat=cbNeeded;
  5115. goto MoreDataError;
  5116. }
  5117. //copy the data
  5118. memcpy(pbFormat, pwszFormat, cbNeeded);
  5119. //copy the size
  5120. *pcbFormat=cbNeeded;
  5121. fResult=TRUE;
  5122. CommonReturn:
  5123. if(pwsz)
  5124. free(pwsz);
  5125. if(pwszEntryFormat)
  5126. LocalFree((HLOCAL)pwszEntryFormat);
  5127. if(pwszAltName)
  5128. free(pwszAltName);
  5129. if(fMethodAllocated)
  5130. {
  5131. if(pwszMethod)
  5132. free(pwszMethod);
  5133. }
  5134. if(pInfo)
  5135. free(pInfo);
  5136. return fResult;
  5137. ErrorReturn:
  5138. fResult=FALSE;
  5139. goto CommonReturn;
  5140. SET_ERROR(InvalidArg, E_INVALIDARG);
  5141. TRACE_ERROR(DecodeGenericError);
  5142. TRACE_ERROR(LoadStringError);
  5143. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  5144. TRACE_ERROR(FormatMsgError);
  5145. TRACE_ERROR(FormatAltNameError);
  5146. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  5147. }
  5148. //--------------------------------------------------------------------------
  5149. //
  5150. // FormatKeyUsageBLOB
  5151. //--------------------------------------------------------------------------
  5152. static BOOL
  5153. WINAPI
  5154. FormatKeyUsageBLOB(
  5155. DWORD dwCertEncodingType,
  5156. DWORD dwFormatType,
  5157. DWORD dwFormatStrType,
  5158. void *pFormatStruct,
  5159. LPCSTR lpszStructType,
  5160. PCRYPT_BIT_BLOB pInfo,
  5161. void *pbFormat,
  5162. DWORD *pcbFormat)
  5163. {
  5164. LPWSTR pwszFinal=NULL;
  5165. LPWSTR pwszFormat=NULL;
  5166. LPWSTR pwsz=NULL;
  5167. LPWSTR pwszByte=NULL;
  5168. WCHAR wszKeyUsage[KEY_USAGE_SIZE+1];
  5169. DWORD cbNeeded=0;
  5170. BOOL fResult=FALSE;
  5171. LPWSTR pwszTemp;
  5172. pwsz=(LPWSTR)malloc(sizeof(WCHAR));
  5173. if(NULL==pwsz)
  5174. goto MemoryError;
  5175. *pwsz=L'\0';
  5176. //format the 1st byte
  5177. if(pInfo->pbData[0] & CERT_DIGITAL_SIGNATURE_KEY_USAGE)
  5178. {
  5179. if(!LoadStringU(hFrmtFuncInst, IDS_DIG_SIG, wszKeyUsage, KEY_USAGE_SIZE))
  5180. goto LoadStringError;
  5181. #if (0) // DSIE: Bug 27436
  5182. pwsz=(LPWSTR)realloc(pwsz,
  5183. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
  5184. if(NULL==pwsz)
  5185. goto MemoryError;
  5186. #endif
  5187. pwszTemp=(LPWSTR)realloc(pwsz,
  5188. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
  5189. if(NULL==pwszTemp)
  5190. goto MemoryError;
  5191. pwsz = pwszTemp;
  5192. wcscat(pwsz, wszKeyUsage);
  5193. wcscat(pwsz, wszCOMMA);
  5194. }
  5195. if(pInfo->pbData[0] & CERT_NON_REPUDIATION_KEY_USAGE)
  5196. {
  5197. if(!LoadStringU(hFrmtFuncInst, IDS_NON_REPUDIATION, wszKeyUsage, KEY_USAGE_SIZE))
  5198. goto LoadStringError;
  5199. #if (0) // DSIE: Bug 27436
  5200. pwsz=(LPWSTR)realloc(pwsz,
  5201. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
  5202. if(NULL==pwsz)
  5203. goto MemoryError;
  5204. #endif
  5205. pwszTemp=(LPWSTR)realloc(pwsz,
  5206. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
  5207. if(NULL==pwszTemp)
  5208. goto MemoryError;
  5209. pwsz = pwszTemp;
  5210. wcscat(pwsz, wszKeyUsage);
  5211. wcscat(pwsz, wszCOMMA);
  5212. }
  5213. if(pInfo->pbData[0] & CERT_KEY_ENCIPHERMENT_KEY_USAGE )
  5214. {
  5215. if(!LoadStringU(hFrmtFuncInst, IDS_KEY_ENCIPHERMENT, wszKeyUsage, KEY_USAGE_SIZE))
  5216. goto LoadStringError;
  5217. #if (0) // DSIE: Bug 27436
  5218. pwsz=(LPWSTR)realloc(pwsz,
  5219. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
  5220. if(NULL==pwsz)
  5221. goto MemoryError;
  5222. #endif
  5223. pwszTemp=(LPWSTR)realloc(pwsz,
  5224. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
  5225. if(NULL==pwszTemp)
  5226. goto MemoryError;
  5227. pwsz = pwszTemp;
  5228. wcscat(pwsz, wszKeyUsage);
  5229. wcscat(pwsz, wszCOMMA);
  5230. }
  5231. if(pInfo->pbData[0] & CERT_DATA_ENCIPHERMENT_KEY_USAGE )
  5232. {
  5233. if(!LoadStringU(hFrmtFuncInst, IDS_DATA_ENCIPHERMENT, wszKeyUsage, KEY_USAGE_SIZE))
  5234. goto LoadStringError;
  5235. #if (0) // DSIE: Bug 27436
  5236. pwsz=(LPWSTR)realloc(pwsz,
  5237. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
  5238. if(NULL==pwsz)
  5239. goto MemoryError;
  5240. #endif
  5241. pwszTemp=(LPWSTR)realloc(pwsz,
  5242. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
  5243. if(NULL==pwszTemp)
  5244. goto MemoryError;
  5245. pwsz = pwszTemp;
  5246. wcscat(pwsz, wszKeyUsage);
  5247. wcscat(pwsz, wszCOMMA);
  5248. }
  5249. if(pInfo->pbData[0] & CERT_KEY_AGREEMENT_KEY_USAGE )
  5250. {
  5251. if(!LoadStringU(hFrmtFuncInst, IDS_KEY_AGREEMENT, wszKeyUsage, KEY_USAGE_SIZE))
  5252. goto LoadStringError;
  5253. #if (0) // DSIE: Bug 27436
  5254. pwsz=(LPWSTR)realloc(pwsz,
  5255. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
  5256. if(NULL==pwsz)
  5257. goto MemoryError;
  5258. #endif
  5259. pwszTemp=(LPWSTR)realloc(pwsz,
  5260. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
  5261. if(NULL==pwszTemp)
  5262. goto MemoryError;
  5263. pwsz = pwszTemp;
  5264. wcscat(pwsz, wszKeyUsage);
  5265. wcscat(pwsz, wszCOMMA);
  5266. }
  5267. if(pInfo->pbData[0] & CERT_KEY_CERT_SIGN_KEY_USAGE )
  5268. {
  5269. if(!LoadStringU(hFrmtFuncInst, IDS_CERT_SIGN, wszKeyUsage, KEY_USAGE_SIZE))
  5270. goto LoadStringError;
  5271. #if (0) // DSIE: Bug 27436
  5272. pwsz=(LPWSTR)realloc(pwsz,
  5273. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
  5274. if(NULL==pwsz)
  5275. goto MemoryError;
  5276. #endif
  5277. pwszTemp=(LPWSTR)realloc(pwsz,
  5278. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
  5279. if(NULL==pwszTemp)
  5280. goto MemoryError;
  5281. pwsz = pwszTemp;
  5282. wcscat(pwsz, wszKeyUsage);
  5283. wcscat(pwsz, wszCOMMA);
  5284. }
  5285. if(pInfo->pbData[0] & CERT_OFFLINE_CRL_SIGN_KEY_USAGE )
  5286. {
  5287. if(!LoadStringU(hFrmtFuncInst, IDS_OFFLINE_CRL_SIGN, wszKeyUsage, KEY_USAGE_SIZE))
  5288. goto LoadStringError;
  5289. #if (0) // DSIE: Bug 27436
  5290. pwsz=(LPWSTR)realloc(pwsz,
  5291. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
  5292. if(NULL==pwsz)
  5293. goto MemoryError;
  5294. #endif
  5295. pwszTemp=(LPWSTR)realloc(pwsz,
  5296. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
  5297. if(NULL==pwszTemp)
  5298. goto MemoryError;
  5299. pwsz = pwszTemp;
  5300. wcscat(pwsz, wszKeyUsage);
  5301. wcscat(pwsz, wszCOMMA);
  5302. }
  5303. if(pInfo->pbData[0] & CERT_CRL_SIGN_KEY_USAGE )
  5304. {
  5305. if(!LoadStringU(hFrmtFuncInst, IDS_CRL_SIGN, wszKeyUsage, KEY_USAGE_SIZE))
  5306. goto LoadStringError;
  5307. #if (0) // DSIE: Bug 27436
  5308. pwsz=(LPWSTR)realloc(pwsz,
  5309. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
  5310. if(NULL==pwsz)
  5311. goto MemoryError;
  5312. #endif
  5313. pwszTemp=(LPWSTR)realloc(pwsz,
  5314. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
  5315. if(NULL==pwszTemp)
  5316. goto MemoryError;
  5317. pwsz = pwszTemp;
  5318. wcscat(pwsz, wszKeyUsage);
  5319. wcscat(pwsz, wszCOMMA);
  5320. }
  5321. if(pInfo->pbData[0] & CERT_ENCIPHER_ONLY_KEY_USAGE )
  5322. {
  5323. if(!LoadStringU(hFrmtFuncInst, IDS_ENCIPHER_ONLY, wszKeyUsage, KEY_USAGE_SIZE))
  5324. goto LoadStringError;
  5325. #if (0) // DSIE: Bug 27436
  5326. pwsz=(LPWSTR)realloc(pwsz,
  5327. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
  5328. if(NULL==pwsz)
  5329. goto MemoryError;
  5330. #endif
  5331. pwszTemp=(LPWSTR)realloc(pwsz,
  5332. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
  5333. if(NULL==pwszTemp)
  5334. goto MemoryError;
  5335. pwsz = pwszTemp;
  5336. wcscat(pwsz, wszKeyUsage);
  5337. wcscat(pwsz, wszCOMMA);
  5338. }
  5339. //deal with the second byte
  5340. if(pInfo->cbData>=2)
  5341. {
  5342. if(pInfo->pbData[1] & CERT_DECIPHER_ONLY_KEY_USAGE )
  5343. {
  5344. if(!LoadStringU(hFrmtFuncInst, IDS_DECIPHER_ONLY, wszKeyUsage, KEY_USAGE_SIZE))
  5345. goto LoadStringError;
  5346. #if (0) // DSIE: Bug 27436
  5347. pwsz=(LPWSTR)realloc(pwsz,
  5348. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
  5349. if(NULL==pwsz)
  5350. goto MemoryError;
  5351. #endif
  5352. pwszTemp=(LPWSTR)realloc(pwsz,
  5353. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
  5354. if(NULL==pwszTemp)
  5355. goto MemoryError;
  5356. pwsz = pwszTemp;
  5357. wcscat(pwsz, wszKeyUsage);
  5358. wcscat(pwsz, wszCOMMA);
  5359. }
  5360. }
  5361. if(0==wcslen(pwsz))
  5362. {
  5363. #if (0) // DSIE: Bug 27436
  5364. pwsz=(LPWSTR)realloc(pwsz, sizeof(WCHAR) * (UNKNOWN_KEY_USAGE_SIZE+1));
  5365. // if(NULL==pwszFormat) DSIE: Bug 27348
  5366. if(NULL==pwsz)
  5367. goto MemoryError;
  5368. #endif
  5369. pwszTemp=(LPWSTR)realloc(pwsz, sizeof(WCHAR) * (UNKNOWN_KEY_USAGE_SIZE+1));
  5370. if(NULL==pwszTemp)
  5371. goto MemoryError;
  5372. pwsz = pwszTemp;
  5373. if(!LoadStringU(hFrmtFuncInst, IDS_UNKNOWN_KEY_USAGE, pwsz,
  5374. UNKNOWN_KEY_USAGE_SIZE))
  5375. goto LoadStringError;
  5376. }
  5377. else
  5378. {
  5379. //get rid of the last comma
  5380. *(pwsz+wcslen(pwsz)-wcslen(wszCOMMA))=L'\0';
  5381. }
  5382. //get the Hex dump of the Key Usage
  5383. cbNeeded=0;
  5384. if(!FormatBytesToHex(
  5385. dwCertEncodingType,
  5386. dwFormatType,
  5387. dwFormatStrType,
  5388. pFormatStruct,
  5389. lpszStructType,
  5390. pInfo->pbData,
  5391. pInfo->cbData,
  5392. NULL,
  5393. &cbNeeded))
  5394. goto FormatBytesToHexError;
  5395. pwszByte=(LPWSTR)malloc(cbNeeded);
  5396. if(NULL==pwszByte)
  5397. goto MemoryError;
  5398. if(!FormatBytesToHex(
  5399. dwCertEncodingType,
  5400. dwFormatType,
  5401. dwFormatStrType,
  5402. pFormatStruct,
  5403. lpszStructType,
  5404. pInfo->pbData,
  5405. pInfo->cbData,
  5406. pwszByte,
  5407. &cbNeeded))
  5408. goto FormatBytesToHexError;
  5409. //convert the WSZ
  5410. if(!FormatMessageUnicode(&pwszFormat, IDS_BIT_BLOB, pwsz,
  5411. pwszByte))
  5412. goto FormatMsgError;
  5413. //
  5414. // DSIE: Fix bug 91502, 256396.
  5415. //
  5416. pwszFinal=(LPWSTR)malloc(sizeof(WCHAR) * (wcslen(pwszFormat)+1+wcslen(wszCRLF)));
  5417. if(NULL==pwszFinal)
  5418. goto MemoryError;
  5419. wcscpy(pwszFinal, pwszFormat);
  5420. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  5421. wcscat(pwszFinal, wszCRLF);
  5422. cbNeeded=sizeof(WCHAR)*(wcslen(pwszFinal)+1);
  5423. //length only calculation
  5424. if(NULL==pbFormat)
  5425. {
  5426. *pcbFormat=cbNeeded;
  5427. fResult=TRUE;
  5428. goto CommonReturn;
  5429. }
  5430. if((*pcbFormat)<cbNeeded)
  5431. {
  5432. *pcbFormat=cbNeeded;
  5433. goto MoreDataError;
  5434. }
  5435. //copy the data
  5436. memcpy(pbFormat, pwszFinal, cbNeeded);
  5437. //copy the size
  5438. *pcbFormat=cbNeeded;
  5439. fResult=TRUE;
  5440. CommonReturn:
  5441. if (pwszFinal)
  5442. free(pwszFinal);
  5443. if(pwszFormat)
  5444. LocalFree((HLOCAL)pwszFormat);
  5445. if(pwsz)
  5446. free(pwsz);
  5447. if(pwszByte)
  5448. free(pwszByte);
  5449. return fResult;
  5450. ErrorReturn:
  5451. fResult=FALSE;
  5452. goto CommonReturn;
  5453. TRACE_ERROR(LoadStringError);
  5454. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  5455. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  5456. TRACE_ERROR(FormatBytesToHexError);
  5457. TRACE_ERROR(FormatMsgError);
  5458. }
  5459. //--------------------------------------------------------------------------
  5460. //
  5461. // FormatKeyUsage: X509_KEY_USAGE
  5462. // szOID_KEY_USAGE
  5463. //--------------------------------------------------------------------------
  5464. static BOOL
  5465. WINAPI
  5466. FormatKeyUsage(
  5467. DWORD dwCertEncodingType,
  5468. DWORD dwFormatType,
  5469. DWORD dwFormatStrType,
  5470. void *pFormatStruct,
  5471. LPCSTR lpszStructType,
  5472. const BYTE *pbEncoded,
  5473. DWORD cbEncoded,
  5474. void *pbFormat,
  5475. DWORD *pcbFormat)
  5476. {
  5477. LPWSTR pwszFormat=NULL;
  5478. WCHAR wszNoInfo[NO_INFO_SIZE];
  5479. PCRYPT_BIT_BLOB pInfo=NULL;
  5480. DWORD cbNeeded=0;
  5481. BOOL fResult=FALSE;
  5482. //check for input parameters
  5483. if((NULL==pbEncoded&& cbEncoded!=0) ||
  5484. (NULL==pcbFormat))
  5485. goto InvalidArg;
  5486. if(cbEncoded==0)
  5487. {
  5488. *pcbFormat=0;
  5489. goto InvalidArg;
  5490. }
  5491. if (!DecodeGenericBLOB(dwCertEncodingType,X509_KEY_USAGE,
  5492. pbEncoded,cbEncoded, (void **)&pInfo))
  5493. goto DecodeGenericError;
  5494. //load the string "Info Not Available"
  5495. if(!LoadStringU(hFrmtFuncInst,IDS_NO_INFO, wszNoInfo, sizeof(wszNoInfo)/sizeof(wszNoInfo[0])))
  5496. goto LoadStringError;
  5497. //check the no data situation
  5498. if(0==pInfo->cbData)
  5499. pwszFormat=wszNoInfo;
  5500. else
  5501. {
  5502. if(1==pInfo->cbData)
  5503. {
  5504. if(0==pInfo->pbData[0])
  5505. pwszFormat=wszNoInfo;
  5506. }
  5507. else
  5508. {
  5509. if(2==pInfo->cbData)
  5510. {
  5511. if((0==pInfo->pbData[0])&&(0==pInfo->pbData[1]))
  5512. pwszFormat=wszNoInfo;
  5513. }
  5514. }
  5515. }
  5516. if(NULL==pwszFormat)
  5517. {
  5518. fResult=FormatKeyUsageBLOB(dwCertEncodingType,
  5519. dwFormatType,
  5520. dwFormatStrType,
  5521. pFormatStruct,
  5522. lpszStructType,
  5523. pInfo,
  5524. pbFormat,
  5525. pcbFormat);
  5526. if(FALSE==fResult)
  5527. goto FormatKeyUsageBLOBError;
  5528. }
  5529. else
  5530. {
  5531. cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
  5532. //length only calculation
  5533. if(NULL==pbFormat)
  5534. {
  5535. *pcbFormat=cbNeeded;
  5536. fResult=TRUE;
  5537. goto CommonReturn;
  5538. }
  5539. if((*pcbFormat)<cbNeeded)
  5540. {
  5541. *pcbFormat=cbNeeded;
  5542. goto MoreDataError;
  5543. }
  5544. //copy the data
  5545. memcpy(pbFormat, pwszFormat, cbNeeded);
  5546. //copy the size
  5547. *pcbFormat=cbNeeded;
  5548. fResult=TRUE;
  5549. }
  5550. CommonReturn:
  5551. if(pInfo)
  5552. free(pInfo);
  5553. return fResult;
  5554. ErrorReturn:
  5555. fResult=FALSE;
  5556. goto CommonReturn;
  5557. SET_ERROR(InvalidArg, E_INVALIDARG);
  5558. TRACE_ERROR(DecodeGenericError);
  5559. TRACE_ERROR(LoadStringError);
  5560. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  5561. TRACE_ERROR(FormatKeyUsageBLOBError);
  5562. }
  5563. //--------------------------------------------------------------------------
  5564. //
  5565. // FormatSMIMECapabilities: PKCS_SMIME_CAPABILITIES
  5566. // szOID_RSA_SMIMECapabilities
  5567. //--------------------------------------------------------------------------
  5568. static BOOL
  5569. WINAPI
  5570. FormatSMIMECapabilities(
  5571. DWORD dwCertEncodingType,
  5572. DWORD dwFormatType,
  5573. DWORD dwFormatStrType,
  5574. void *pFormatStruct,
  5575. LPCSTR lpszStructType,
  5576. const BYTE *pbEncoded,
  5577. DWORD cbEncoded,
  5578. void *pbFormat,
  5579. DWORD *pcbFormat)
  5580. {
  5581. LPWSTR pwszFormat=NULL;
  5582. LPWSTR pwsz=NULL;
  5583. LPWSTR pwszElementFormat=NULL;
  5584. LPWSTR pwszParam=NULL;
  5585. WCHAR wszNoInfo[NO_INFO_SIZE];
  5586. BOOL fParamAllocated=FALSE;
  5587. PCRYPT_SMIME_CAPABILITIES pInfo=NULL;
  5588. DWORD cbNeeded=0;
  5589. BOOL fResult=FALSE;
  5590. DWORD dwIndex =0;
  5591. UINT idsSub=0;
  5592. LPWSTR pwszTemp;
  5593. //check for input parameters
  5594. if((NULL==pbEncoded&& cbEncoded!=0) ||
  5595. (NULL==pcbFormat))
  5596. goto InvalidArg;
  5597. if(cbEncoded==0)
  5598. {
  5599. *pcbFormat=0;
  5600. goto InvalidArg;
  5601. }
  5602. if (!DecodeGenericBLOB(dwCertEncodingType,PKCS_SMIME_CAPABILITIES,
  5603. pbEncoded,cbEncoded, (void **)&pInfo))
  5604. goto DecodeGenericError;
  5605. //check to see if information if available
  5606. if(0==pInfo->cCapability)
  5607. {
  5608. //load the string "Info Not Available"
  5609. if(!LoadStringU(hFrmtFuncInst,IDS_NO_INFO, wszNoInfo, sizeof(wszNoInfo)/sizeof(wszNoInfo[0])))
  5610. goto LoadStringError;
  5611. pwszFormat=wszNoInfo;
  5612. }
  5613. else
  5614. {
  5615. pwsz=(LPWSTR)malloc(sizeof(WCHAR));
  5616. if(NULL==pwsz)
  5617. goto MemoryError;
  5618. *pwsz=L'\0';
  5619. for(dwIndex=0; dwIndex < pInfo->cCapability; dwIndex++)
  5620. {
  5621. fParamAllocated=FALSE;
  5622. //strcat ", " if single line. No need for multi-line
  5623. if(0!=wcslen(pwsz))
  5624. {
  5625. if(0==(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
  5626. wcscat(pwsz, wszCOMMA);
  5627. }
  5628. if(0!=(pInfo->rgCapability)[dwIndex].Parameters.cbData)
  5629. {
  5630. cbNeeded=0;
  5631. if(!FormatBytesToHex(
  5632. dwCertEncodingType,
  5633. dwFormatType,
  5634. dwFormatStrType,
  5635. pFormatStruct,
  5636. lpszStructType,
  5637. (pInfo->rgCapability)[dwIndex].Parameters.pbData,
  5638. (pInfo->rgCapability)[dwIndex].Parameters.cbData,
  5639. NULL,
  5640. &cbNeeded))
  5641. goto FormatBytesToHexError;
  5642. pwszParam=(LPWSTR)malloc(cbNeeded);
  5643. if(NULL==pwszParam)
  5644. goto MemoryError;
  5645. fParamAllocated=TRUE;
  5646. if(!FormatBytesToHex(
  5647. dwCertEncodingType,
  5648. dwFormatType,
  5649. dwFormatStrType,
  5650. pFormatStruct,
  5651. lpszStructType,
  5652. (pInfo->rgCapability)[dwIndex].Parameters.pbData,
  5653. (pInfo->rgCapability)[dwIndex].Parameters.cbData,
  5654. pwszParam,
  5655. &cbNeeded))
  5656. goto FormatBytesToHexError;
  5657. //decide between single line and mulitple line format
  5658. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  5659. idsSub=IDS_MIME_CAPABILITY_MULTI;
  5660. else
  5661. idsSub=IDS_MIME_CAPABILITY;
  5662. //format the element string
  5663. if(!FormatMessageUnicode(&pwszElementFormat, idsSub,
  5664. dwIndex+1,
  5665. (pInfo->rgCapability)[dwIndex].pszObjId,
  5666. pwszParam))
  5667. goto FormatMsgError;
  5668. }
  5669. else
  5670. {
  5671. //decide between single line and mulitple line format
  5672. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  5673. idsSub=IDS_MIME_CAPABILITY_NO_PARAM_MULTI;
  5674. else
  5675. idsSub=IDS_MIME_CAPABILITY_NO_PARAM;
  5676. //format the element string
  5677. if(!FormatMessageUnicode(&pwszElementFormat, idsSub,
  5678. dwIndex+1,
  5679. (pInfo->rgCapability)[dwIndex].pszObjId))
  5680. goto FormatMsgError;
  5681. }
  5682. #if (0) // DSIE: Bug 27436
  5683. pwsz=(LPWSTR)realloc(pwsz,
  5684. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszElementFormat)+1));
  5685. if(NULL==pwsz)
  5686. goto MemoryError;
  5687. #endif
  5688. pwszTemp=(LPWSTR)realloc(pwsz,
  5689. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszElementFormat)+1));
  5690. if(NULL==pwszTemp)
  5691. goto MemoryError;
  5692. pwsz = pwszTemp;
  5693. //strcat the element
  5694. wcscat(pwsz, pwszElementFormat);
  5695. //free the memory
  5696. LocalFree((HLOCAL)pwszElementFormat);
  5697. pwszElementFormat=NULL;
  5698. if(fParamAllocated)
  5699. free(pwszParam);
  5700. pwszParam=NULL;
  5701. }
  5702. pwszFormat=pwsz;
  5703. }
  5704. cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
  5705. //length only calculation
  5706. if(NULL==pbFormat)
  5707. {
  5708. *pcbFormat=cbNeeded;
  5709. fResult=TRUE;
  5710. goto CommonReturn;
  5711. }
  5712. if((*pcbFormat)<cbNeeded)
  5713. {
  5714. *pcbFormat=cbNeeded;
  5715. goto MoreDataError;
  5716. }
  5717. //copy the data
  5718. memcpy(pbFormat, pwszFormat, cbNeeded);
  5719. //copy the size
  5720. *pcbFormat=cbNeeded;
  5721. fResult=TRUE;
  5722. CommonReturn:
  5723. if(pwszElementFormat)
  5724. LocalFree((HLOCAL)pwszElementFormat);
  5725. if(fParamAllocated)
  5726. {
  5727. if(pwszParam)
  5728. free(pwszParam);
  5729. }
  5730. if(pInfo)
  5731. free(pInfo);
  5732. if(pwsz)
  5733. free(pwsz);
  5734. return fResult;
  5735. ErrorReturn:
  5736. fResult=FALSE;
  5737. goto CommonReturn;
  5738. SET_ERROR(InvalidArg, E_INVALIDARG);
  5739. TRACE_ERROR(DecodeGenericError);
  5740. TRACE_ERROR(LoadStringError);
  5741. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  5742. TRACE_ERROR(FormatMsgError);
  5743. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  5744. TRACE_ERROR(FormatBytesToHexError);
  5745. }
  5746. //--------------------------------------------------------------------------
  5747. //
  5748. // FormatFinancialCriteria: SPC_FINANCIAL_CRITERIA_OBJID
  5749. // SPC_FINANCIAL_CRITERIA_STRUCT
  5750. //--------------------------------------------------------------------------
  5751. static BOOL
  5752. WINAPI
  5753. FormatFinancialCriteria(
  5754. DWORD dwCertEncodingType,
  5755. DWORD dwFormatType,
  5756. DWORD dwFormatStrType,
  5757. void *pFormatStruct,
  5758. LPCSTR lpszStructType,
  5759. const BYTE *pbEncoded,
  5760. DWORD cbEncoded,
  5761. void *pbFormat,
  5762. DWORD *pcbFormat)
  5763. {
  5764. LPWSTR pwszFormat=NULL;
  5765. WCHAR wszYesNo[YES_NO_SIZE];
  5766. WCHAR wszAvailable[AVAIL_SIZE];
  5767. PSPC_FINANCIAL_CRITERIA pInfo=NULL;
  5768. DWORD cbNeeded=0;
  5769. BOOL fResult=FALSE;
  5770. UINT idsInfo=0;
  5771. //check for input parameters
  5772. if((NULL==pbEncoded&& cbEncoded!=0) ||
  5773. (NULL==pcbFormat))
  5774. goto InvalidArg;
  5775. if(cbEncoded==0)
  5776. {
  5777. *pcbFormat=0;
  5778. goto InvalidArg;
  5779. }
  5780. if (!DecodeGenericBLOB(dwCertEncodingType,SPC_FINANCIAL_CRITERIA_STRUCT,
  5781. pbEncoded,cbEncoded, (void **)&pInfo))
  5782. goto DecodeGenericError;
  5783. //load the string for financial info
  5784. if(TRUE==pInfo->fFinancialInfoAvailable)
  5785. {
  5786. if(TRUE==pInfo->fMeetsCriteria)
  5787. idsInfo=IDS_YES;
  5788. else
  5789. idsInfo=IDS_NO;
  5790. //load the string for "yes" or "no"
  5791. if(!LoadStringU(hFrmtFuncInst,idsInfo, wszYesNo, sizeof(wszYesNo)/sizeof(wszYesNo[0])))
  5792. goto LoadStringError;
  5793. //mark the avaiblility of the financial info
  5794. idsInfo=IDS_AVAILABLE;
  5795. }
  5796. else
  5797. idsInfo=IDS_NOT_AVAILABLE;
  5798. if(!LoadStringU(hFrmtFuncInst,idsInfo, wszAvailable,
  5799. sizeof(wszAvailable)/sizeof(wszAvailable[0])))
  5800. goto LoadStringError;
  5801. //format the output string
  5802. if(TRUE==pInfo->fFinancialInfoAvailable)
  5803. {
  5804. //decide between single line and mulitple line format
  5805. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  5806. idsInfo=IDS_SPC_FINANCIAL_AVAIL_MULTI;
  5807. else
  5808. idsInfo=IDS_SPC_FINANCIAL_AVAIL;
  5809. if(!FormatMessageUnicode(&pwszFormat, idsInfo,
  5810. wszAvailable, wszYesNo))
  5811. goto FormatMsgError;
  5812. }
  5813. else
  5814. {
  5815. //decide between single line and mulitple line format
  5816. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  5817. idsInfo=IDS_SPC_FINANCIAL_NOT_AVAIL_MULTI;
  5818. else
  5819. idsInfo=IDS_SPC_FINANCIAL_NOT_AVAIL;
  5820. if(!FormatMessageUnicode(&pwszFormat, idsInfo,
  5821. wszAvailable))
  5822. goto FormatMsgError;
  5823. }
  5824. cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
  5825. //length only calculation
  5826. if(NULL==pbFormat)
  5827. {
  5828. *pcbFormat=cbNeeded;
  5829. fResult=TRUE;
  5830. goto CommonReturn;
  5831. }
  5832. if((*pcbFormat)<cbNeeded)
  5833. {
  5834. *pcbFormat=cbNeeded;
  5835. goto MoreDataError;
  5836. }
  5837. //copy the data
  5838. memcpy(pbFormat, pwszFormat, cbNeeded);
  5839. //copy the size
  5840. *pcbFormat=cbNeeded;
  5841. fResult=TRUE;
  5842. CommonReturn:
  5843. if(pwszFormat)
  5844. LocalFree((HLOCAL)pwszFormat);
  5845. if(pInfo)
  5846. free(pInfo);
  5847. return fResult;
  5848. ErrorReturn:
  5849. fResult=FALSE;
  5850. goto CommonReturn;
  5851. SET_ERROR(InvalidArg, E_INVALIDARG);
  5852. TRACE_ERROR(DecodeGenericError);
  5853. TRACE_ERROR(LoadStringError);
  5854. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  5855. TRACE_ERROR(FormatMsgError);
  5856. }
  5857. //--------------------------------------------------------------------------
  5858. //
  5859. // FormatNextUpdateLocation: szOID_NEXT_UPDATE_LOCATION
  5860. //--------------------------------------------------------------------------
  5861. static BOOL
  5862. WINAPI
  5863. FormatNextUpdateLocation(
  5864. DWORD dwCertEncodingType,
  5865. DWORD dwFormatType,
  5866. DWORD dwFormatStrType,
  5867. void *pFormatStruct,
  5868. LPCSTR lpszStructType,
  5869. const BYTE *pbEncoded,
  5870. DWORD cbEncoded,
  5871. void *pbFormat,
  5872. DWORD *pcbFormat)
  5873. {
  5874. PCERT_ALT_NAME_INFO pInfo=NULL;
  5875. BOOL fResult=FALSE;
  5876. //check for input parameters
  5877. if((NULL==pbEncoded && cbEncoded!=0) ||
  5878. (NULL==pcbFormat))
  5879. goto InvalidArg;
  5880. if(cbEncoded==0)
  5881. {
  5882. *pcbFormat=0;
  5883. goto InvalidArg;
  5884. }
  5885. if (!DecodeGenericBLOB(dwCertEncodingType,szOID_NEXT_UPDATE_LOCATION,
  5886. pbEncoded,cbEncoded, (void **)&pInfo))
  5887. goto DecodeGenericError;
  5888. //format the alternative name
  5889. fResult=FormatAltNameInfo(dwCertEncodingType, dwFormatType,dwFormatStrType,
  5890. pFormatStruct,
  5891. 0, //no prefix
  5892. TRUE,
  5893. pInfo, pbFormat, pcbFormat);
  5894. if(FALSE==fResult)
  5895. goto FormatAltNameError;
  5896. CommonReturn:
  5897. if(pInfo)
  5898. free(pInfo);
  5899. return fResult;
  5900. ErrorReturn:
  5901. fResult=FALSE;
  5902. goto CommonReturn;
  5903. SET_ERROR(InvalidArg, E_INVALIDARG);
  5904. TRACE_ERROR(DecodeGenericError);
  5905. TRACE_ERROR(FormatAltNameError);
  5906. }
  5907. //--------------------------------------------------------------------------
  5908. //
  5909. // FormatSubjectKeyID: szOID_SUBJECT_KEY_IDENTIFIER
  5910. //--------------------------------------------------------------------------
  5911. static BOOL
  5912. WINAPI
  5913. FormatSubjectKeyID(
  5914. DWORD dwCertEncodingType,
  5915. DWORD dwFormatType,
  5916. DWORD dwFormatStrType,
  5917. void *pFormatStruct,
  5918. LPCSTR lpszStructType,
  5919. const BYTE *pbEncoded,
  5920. DWORD cbEncoded,
  5921. void *pbFormat,
  5922. DWORD *pcbFormat)
  5923. {
  5924. PCRYPT_DATA_BLOB pInfo=NULL;
  5925. BOOL fResult=FALSE;
  5926. WCHAR wszNoInfo[NO_INFO_SIZE];
  5927. DWORD cbNeeded=0;
  5928. // DSIE: Fix bug 91502
  5929. LPWSTR pwsz=NULL;
  5930. LPWSTR pwszFormat=NULL;
  5931. LPWSTR pwszKeyID=NULL;
  5932. LPWSTR pwszKeyIDFormat=NULL;
  5933. LPWSTR pwszTemp;
  5934. //check for input parameters
  5935. if((NULL==pbEncoded && cbEncoded!=0) ||
  5936. (NULL==pcbFormat))
  5937. goto InvalidArg;
  5938. if(cbEncoded==0)
  5939. {
  5940. *pcbFormat=0;
  5941. goto InvalidArg;
  5942. }
  5943. if (!DecodeGenericBLOB(dwCertEncodingType,szOID_SUBJECT_KEY_IDENTIFIER,
  5944. pbEncoded,cbEncoded, (void **)&pInfo))
  5945. goto DecodeGenericError;
  5946. //format the key subject ID
  5947. //handle NULL data case
  5948. if(0==pInfo->cbData)
  5949. {
  5950. //load the string "Info Not Available"
  5951. if(!LoadStringU(hFrmtFuncInst,IDS_NO_INFO, wszNoInfo, sizeof(wszNoInfo)/sizeof(wszNoInfo[0])))
  5952. goto LoadStringError;
  5953. pwszFormat = wszNoInfo;
  5954. }
  5955. else
  5956. {
  5957. pwsz=(LPWSTR)malloc(sizeof(WCHAR));
  5958. if(NULL==pwsz)
  5959. goto MemoryError;
  5960. *pwsz=L'\0';
  5961. cbNeeded=0;
  5962. if(!FormatBytesToHex(dwCertEncodingType,
  5963. dwFormatType,
  5964. dwFormatStrType,
  5965. NULL,
  5966. NULL,
  5967. pInfo->pbData,
  5968. pInfo->cbData,
  5969. NULL,
  5970. &cbNeeded))
  5971. goto KeyIDBytesToHexError;
  5972. pwszKeyID=(LPWSTR)malloc(cbNeeded);
  5973. if(NULL==pwszKeyID)
  5974. goto MemoryError;
  5975. if(!FormatBytesToHex(dwCertEncodingType,
  5976. dwFormatType,
  5977. dwFormatStrType,
  5978. NULL,
  5979. NULL,
  5980. pInfo->pbData,
  5981. pInfo->cbData,
  5982. pwszKeyID,
  5983. &cbNeeded))
  5984. goto KeyIDBytesToHexError;
  5985. if(!FormatMessageUnicode(&pwszKeyIDFormat,IDS_UNICODE_STRING,pwszKeyID))
  5986. goto FormatMsgError;
  5987. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  5988. pwszTemp=(LPWSTR)realloc(pwsz,
  5989. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(pwszKeyIDFormat)+wcslen(wszCRLF)+1));
  5990. else
  5991. pwszTemp=(LPWSTR)realloc(pwsz,
  5992. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(pwszKeyIDFormat)+1));
  5993. if(NULL==pwszTemp)
  5994. goto MemoryError;
  5995. pwsz = pwszTemp;
  5996. //strcat the KeyID
  5997. wcscat(pwsz,pwszKeyIDFormat);
  5998. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  5999. wcscat(pwsz, wszCRLF);
  6000. pwszFormat=pwsz;
  6001. }
  6002. cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
  6003. //length only calculation
  6004. if(NULL==pbFormat)
  6005. {
  6006. *pcbFormat=cbNeeded;
  6007. fResult=TRUE;
  6008. goto CommonReturn;
  6009. }
  6010. if((*pcbFormat)<cbNeeded)
  6011. {
  6012. *pcbFormat=cbNeeded;
  6013. goto MoreDataError;
  6014. }
  6015. //copy the data
  6016. memcpy(pbFormat, pwszFormat, cbNeeded);
  6017. //copy the size
  6018. *pcbFormat=cbNeeded;
  6019. fResult=TRUE;
  6020. CommonReturn:
  6021. if(pwszKeyID)
  6022. free(pwszKeyID);
  6023. if(pwszKeyIDFormat)
  6024. LocalFree((HLOCAL)pwszKeyIDFormat);
  6025. if(pwsz)
  6026. free(pwsz);
  6027. if(pInfo)
  6028. free(pInfo);
  6029. return fResult;
  6030. ErrorReturn:
  6031. fResult=FALSE;
  6032. goto CommonReturn;
  6033. SET_ERROR(InvalidArg, E_INVALIDARG);
  6034. TRACE_ERROR(DecodeGenericError);
  6035. TRACE_ERROR(FormatMsgError);
  6036. TRACE_ERROR(KeyIDBytesToHexError);
  6037. //TRACE_ERROR(FormatBytestToHexError);
  6038. TRACE_ERROR(LoadStringError);
  6039. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  6040. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  6041. }
  6042. //--------------------------------------------------------------------------
  6043. //
  6044. // FormatAuthorityKeyID: szOID_AUTHORITY_KEY_IDENTIFIER
  6045. // X509_AUTHORITY_KEY_ID
  6046. //--------------------------------------------------------------------------
  6047. static BOOL
  6048. WINAPI
  6049. FormatAuthorityKeyID(
  6050. DWORD dwCertEncodingType,
  6051. DWORD dwFormatType,
  6052. DWORD dwFormatStrType,
  6053. void *pFormatStruct,
  6054. LPCSTR lpszStructType,
  6055. const BYTE *pbEncoded,
  6056. DWORD cbEncoded,
  6057. void *pbFormat,
  6058. DWORD *pcbFormat)
  6059. {
  6060. LPWSTR pwszFormat=NULL;
  6061. LPWSTR pwsz=NULL;
  6062. LPWSTR pwszKeyID=NULL;
  6063. LPWSTR pwszKeyIDFormat=NULL;
  6064. LPWSTR pwszCertIssuer=NULL;
  6065. LPWSTR pwszCertIssuerFormat=NULL;
  6066. LPWSTR pwszCertNumber=NULL;
  6067. LPWSTR pwszCertNumberFormat=NULL;
  6068. BYTE *pByte=NULL;
  6069. DWORD dwByteIndex=0;
  6070. WCHAR wszNoInfo[NO_INFO_SIZE];
  6071. PCERT_AUTHORITY_KEY_ID_INFO pInfo=NULL;
  6072. DWORD cbNeeded=0;
  6073. BOOL fResult=FALSE;
  6074. UINT ids=0;
  6075. LPWSTR pwszTemp;
  6076. //check for input parameters
  6077. if((NULL==pbEncoded && cbEncoded!=0) ||
  6078. (NULL==pcbFormat))
  6079. goto InvalidArg;
  6080. if(cbEncoded==0)
  6081. {
  6082. *pcbFormat=0;
  6083. goto InvalidArg;
  6084. }
  6085. if (!DecodeGenericBLOB(dwCertEncodingType,X509_AUTHORITY_KEY_ID,
  6086. pbEncoded,cbEncoded, (void **)&pInfo))
  6087. goto DecodeGenericError;
  6088. //load the string "Info Not Available"
  6089. if((0==pInfo->KeyId.cbData)&&(0==pInfo->CertIssuer.cbData)
  6090. &&(0==pInfo->CertSerialNumber.cbData))
  6091. {
  6092. if(!LoadStringU(hFrmtFuncInst,IDS_NO_INFO, wszNoInfo, sizeof(wszNoInfo)/sizeof(wszNoInfo[0])))
  6093. goto LoadStringError;
  6094. pwszFormat=wszNoInfo;
  6095. }
  6096. else
  6097. {
  6098. pwsz=(LPWSTR)malloc(sizeof(WCHAR));
  6099. if(NULL==pwsz)
  6100. goto MemoryError;
  6101. *pwsz=L'\0';
  6102. //format the three fields in the struct: KeyID; CertIssuer; CertSerialNumber
  6103. if(0!=pInfo->KeyId.cbData)
  6104. {
  6105. cbNeeded=0;
  6106. if(!FormatBytesToHex(dwCertEncodingType,
  6107. dwFormatType,
  6108. dwFormatStrType,
  6109. NULL,
  6110. NULL,
  6111. pInfo->KeyId.pbData,
  6112. pInfo->KeyId.cbData,
  6113. NULL,
  6114. &cbNeeded))
  6115. goto KeyIDBytesToHexError;
  6116. pwszKeyID=(LPWSTR)malloc(cbNeeded);
  6117. if(NULL==pwszKeyID)
  6118. goto MemoryError;
  6119. if(!FormatBytesToHex(dwCertEncodingType,
  6120. dwFormatType,
  6121. dwFormatStrType,
  6122. NULL,
  6123. NULL,
  6124. pInfo->KeyId.pbData,
  6125. pInfo->KeyId.cbData,
  6126. pwszKeyID,
  6127. &cbNeeded))
  6128. goto KeyIDBytesToHexError;
  6129. if(!FormatMessageUnicode(&pwszKeyIDFormat, IDS_AUTH_KEY_ID,pwszKeyID))
  6130. goto FormatMsgError;
  6131. #if (0) // DSIE: Bug 27436
  6132. pwsz=(LPWSTR)realloc(pwsz,
  6133. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszKeyIDFormat)+1));
  6134. if(NULL==pwsz)
  6135. goto MemoryError;
  6136. #endif
  6137. #if (0) //DSIE: Potential AV. Need two more chars, \r\n, for multi-lines.
  6138. pwszTemp=(LPWSTR)realloc(pwsz,
  6139. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszKeyIDFormat)+1));
  6140. #else
  6141. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  6142. pwszTemp=(LPWSTR)realloc(pwsz,
  6143. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszKeyIDFormat)+wcslen(wszCRLF)+1));
  6144. else
  6145. pwszTemp=(LPWSTR)realloc(pwsz,
  6146. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszKeyIDFormat)+1));
  6147. #endif
  6148. if(NULL==pwszTemp)
  6149. goto MemoryError;
  6150. pwsz = pwszTemp;
  6151. //strcat the KeyID
  6152. wcscat(pwsz,pwszKeyIDFormat);
  6153. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  6154. wcscat(pwsz, wszCRLF);
  6155. }
  6156. //format certIssuer
  6157. if(0!=pInfo->CertIssuer.cbData)
  6158. {
  6159. //strcat ", " if there is data before
  6160. if(0!=wcslen(pwsz))
  6161. {
  6162. if(0==(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
  6163. wcscat(pwsz, wszCOMMA);
  6164. }
  6165. if(!CryptDllFormatNameAll(
  6166. dwCertEncodingType,
  6167. dwFormatType,
  6168. dwFormatStrType,
  6169. pFormatStruct,
  6170. IDS_ONE_TAB,
  6171. TRUE, //memory allocation
  6172. pInfo->CertIssuer.pbData,
  6173. pInfo->CertIssuer.cbData,
  6174. (void **)&pwszCertIssuer,
  6175. NULL))
  6176. goto GetCertNameError;
  6177. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  6178. ids=IDS_AUTH_CERT_ISSUER_MULTI;
  6179. else
  6180. ids=IDS_AUTH_CERT_ISSUER;
  6181. if(!FormatMessageUnicode(&pwszCertIssuerFormat, ids,pwszCertIssuer))
  6182. goto FormatMsgError;
  6183. #if (0) // DSIE: Bug 27436
  6184. pwsz=(LPWSTR)realloc(pwsz,
  6185. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszCertIssuerFormat)+1));
  6186. if(NULL==pwsz)
  6187. goto MemoryError;
  6188. #endif
  6189. pwszTemp=(LPWSTR)realloc(pwsz,
  6190. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszCertIssuerFormat)+1));
  6191. if(NULL==pwszTemp)
  6192. goto MemoryError;
  6193. pwsz = pwszTemp;
  6194. wcscat(pwsz,pwszCertIssuerFormat);
  6195. //no need for \n for CERT_NAME
  6196. }
  6197. //format CertSerialNumber
  6198. if(0!=pInfo->CertSerialNumber.cbData)
  6199. {
  6200. //strcat ", " if there is data before
  6201. if(0!=wcslen(pwsz))
  6202. {
  6203. if(0==(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
  6204. wcscat(pwsz, wszCOMMA);
  6205. }
  6206. //copy the serial number into the correct order
  6207. pByte=(BYTE *)malloc(pInfo->CertSerialNumber.cbData);
  6208. if(NULL==pByte)
  6209. goto MemoryError;
  6210. for(dwByteIndex=0; dwByteIndex <pInfo->CertSerialNumber.cbData;
  6211. dwByteIndex++)
  6212. {
  6213. pByte[dwByteIndex]=*(pInfo->CertSerialNumber.pbData+
  6214. pInfo->CertSerialNumber.cbData-1-dwByteIndex);
  6215. }
  6216. cbNeeded=0;
  6217. if(!FormatBytesToHex(dwCertEncodingType,
  6218. dwFormatType,
  6219. dwFormatStrType,
  6220. NULL,
  6221. NULL,
  6222. pByte,
  6223. pInfo->CertSerialNumber.cbData,
  6224. NULL,
  6225. &cbNeeded))
  6226. goto CertNumberBytesToHexError;
  6227. pwszCertNumber=(LPWSTR)malloc(cbNeeded);
  6228. if(NULL==pwszCertNumber)
  6229. goto MemoryError;
  6230. if(!FormatBytesToHex(dwCertEncodingType,
  6231. dwFormatType,
  6232. dwFormatStrType,
  6233. NULL,
  6234. NULL,
  6235. pByte,
  6236. pInfo->CertSerialNumber.cbData,
  6237. pwszCertNumber,
  6238. &cbNeeded))
  6239. goto CertNumberBytesToHexError;
  6240. if(!FormatMessageUnicode(&pwszCertNumberFormat, IDS_AUTH_CERT_NUMBER,pwszCertNumber))
  6241. goto FormatMsgError;
  6242. #if (0) // DSIE: Bug 27436
  6243. pwsz=(LPWSTR)realloc(pwsz,
  6244. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszCertNumberFormat)+1));
  6245. if(NULL==pwsz)
  6246. goto MemoryError;
  6247. #endif
  6248. pwszTemp=(LPWSTR)realloc(pwsz,
  6249. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszCertNumberFormat)+1));
  6250. if(NULL==pwszTemp)
  6251. goto MemoryError;
  6252. pwsz = pwszTemp;
  6253. wcscat(pwsz,pwszCertNumberFormat);
  6254. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  6255. wcscat(pwsz, wszCRLF);
  6256. }
  6257. pwszFormat=pwsz;
  6258. }
  6259. cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
  6260. //length only calculation
  6261. if(NULL==pbFormat)
  6262. {
  6263. *pcbFormat=cbNeeded;
  6264. fResult=TRUE;
  6265. goto CommonReturn;
  6266. }
  6267. if((*pcbFormat)<cbNeeded)
  6268. {
  6269. *pcbFormat=cbNeeded;
  6270. goto MoreDataError;
  6271. }
  6272. //copy the data
  6273. memcpy(pbFormat, pwszFormat, cbNeeded);
  6274. //copy the size
  6275. *pcbFormat=cbNeeded;
  6276. fResult=TRUE;
  6277. CommonReturn:
  6278. if(pByte)
  6279. free(pByte);
  6280. if(pwszKeyID)
  6281. free(pwszKeyID);
  6282. if(pwszKeyIDFormat)
  6283. LocalFree((HLOCAL)pwszKeyIDFormat);
  6284. if(pwszCertIssuer)
  6285. free(pwszCertIssuer);
  6286. if(pwszCertIssuerFormat)
  6287. LocalFree((HLOCAL)pwszCertIssuerFormat);
  6288. if(pwszCertNumber)
  6289. free(pwszCertNumber);
  6290. if(pwszCertNumberFormat)
  6291. LocalFree((HLOCAL)pwszCertNumberFormat);
  6292. if(pwsz)
  6293. free(pwsz);
  6294. if(pInfo)
  6295. free(pInfo);
  6296. return fResult;
  6297. ErrorReturn:
  6298. fResult=FALSE;
  6299. goto CommonReturn;
  6300. SET_ERROR(InvalidArg, E_INVALIDARG);
  6301. TRACE_ERROR(DecodeGenericError);
  6302. TRACE_ERROR(LoadStringError);
  6303. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  6304. TRACE_ERROR(FormatMsgError);
  6305. TRACE_ERROR(KeyIDBytesToHexError);
  6306. TRACE_ERROR(GetCertNameError);
  6307. TRACE_ERROR(CertNumberBytesToHexError);
  6308. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  6309. }
  6310. //--------------------------------------------------------------------------
  6311. //
  6312. // FormatAuthorityKeyID2: szOID_AUTHORITY_KEY_IDENTIFIER2
  6313. // X509_AUTHORITY_KEY_ID2
  6314. //--------------------------------------------------------------------------
  6315. static BOOL
  6316. WINAPI
  6317. FormatAuthorityKeyID2(
  6318. DWORD dwCertEncodingType,
  6319. DWORD dwFormatType,
  6320. DWORD dwFormatStrType,
  6321. void *pFormatStruct,
  6322. LPCSTR lpszStructType,
  6323. const BYTE *pbEncoded,
  6324. DWORD cbEncoded,
  6325. void *pbFormat,
  6326. DWORD *pcbFormat)
  6327. {
  6328. LPWSTR pwszFormat=NULL;
  6329. LPWSTR pwsz=NULL;
  6330. LPWSTR pwszKeyID=NULL;
  6331. LPWSTR pwszKeyIDFormat=NULL;
  6332. LPWSTR pwszCertIssuer=NULL;
  6333. LPWSTR pwszCertIssuerFormat=NULL;
  6334. LPWSTR pwszCertNumber=NULL;
  6335. LPWSTR pwszCertNumberFormat=NULL;
  6336. BYTE *pByte=NULL;
  6337. DWORD dwByteIndex=0;
  6338. WCHAR wszNoInfo[NO_INFO_SIZE];
  6339. PCERT_AUTHORITY_KEY_ID2_INFO pInfo=NULL;
  6340. DWORD cbNeeded=0;
  6341. BOOL fResult=FALSE;
  6342. UINT ids=0;
  6343. LPWSTR pwszTemp;
  6344. //check for input parameters
  6345. if((NULL==pbEncoded && cbEncoded!=0) ||
  6346. (NULL==pcbFormat))
  6347. goto InvalidArg;
  6348. if(cbEncoded==0)
  6349. {
  6350. *pcbFormat=0;
  6351. goto InvalidArg;
  6352. }
  6353. if (!DecodeGenericBLOB(dwCertEncodingType,X509_AUTHORITY_KEY_ID2,
  6354. pbEncoded,cbEncoded, (void **)&pInfo))
  6355. goto DecodeGenericError;
  6356. //load the string "Info Not Available"
  6357. if((0==pInfo->KeyId.cbData)&&(0==pInfo->AuthorityCertIssuer.cAltEntry)
  6358. &&(0==pInfo->AuthorityCertSerialNumber.cbData))
  6359. {
  6360. if(!LoadStringU(hFrmtFuncInst,IDS_NO_INFO, wszNoInfo, sizeof(wszNoInfo)/sizeof(wszNoInfo[0])))
  6361. goto LoadStringError;
  6362. pwszFormat=wszNoInfo;
  6363. }
  6364. else
  6365. {
  6366. pwsz=(LPWSTR)malloc(sizeof(WCHAR));
  6367. if(NULL==pwsz)
  6368. goto MemoryError;
  6369. *pwsz=L'\0';
  6370. //format the three fields in the struct: KeyID; CertIssuer; CertSerialNumber
  6371. if(0!=pInfo->KeyId.cbData)
  6372. {
  6373. cbNeeded=0;
  6374. if(!FormatBytesToHex(dwCertEncodingType,
  6375. dwFormatType,
  6376. dwFormatStrType,
  6377. NULL,
  6378. NULL,
  6379. pInfo->KeyId.pbData,
  6380. pInfo->KeyId.cbData,
  6381. NULL,
  6382. &cbNeeded))
  6383. goto KeyIDBytesToHexError;
  6384. pwszKeyID=(LPWSTR)malloc(cbNeeded);
  6385. if(NULL==pwszKeyID)
  6386. goto MemoryError;
  6387. if(!FormatBytesToHex(dwCertEncodingType,
  6388. dwFormatType,
  6389. dwFormatStrType,
  6390. NULL,
  6391. NULL,
  6392. pInfo->KeyId.pbData,
  6393. pInfo->KeyId.cbData,
  6394. pwszKeyID,
  6395. &cbNeeded))
  6396. goto KeyIDBytesToHexError;
  6397. if(!FormatMessageUnicode(&pwszKeyIDFormat, IDS_AUTH_KEY_ID,pwszKeyID))
  6398. goto FormatMsgError;
  6399. #if (0) // DSIE: Bug 27436
  6400. pwsz=(LPWSTR)realloc(pwsz,
  6401. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+
  6402. wcslen(pwszKeyIDFormat)+1));
  6403. if(NULL==pwsz)
  6404. goto MemoryError;
  6405. #endif
  6406. pwszTemp=(LPWSTR)realloc(pwsz,
  6407. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+
  6408. wcslen(pwszKeyIDFormat)+1));
  6409. if(NULL==pwszTemp)
  6410. goto MemoryError;
  6411. pwsz = pwszTemp;
  6412. wcscat(pwsz,pwszKeyIDFormat);
  6413. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  6414. wcscat(pwsz, wszCRLF);
  6415. }
  6416. //format certIssuer
  6417. if(0!=pInfo->AuthorityCertIssuer.cAltEntry)
  6418. {
  6419. //strcat ", " if there is data before
  6420. if(0!=wcslen(pwsz))
  6421. {
  6422. if(0==(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
  6423. wcscat(pwsz, wszCOMMA);
  6424. }
  6425. cbNeeded=0;
  6426. //need a \t before each entry of the alternative name
  6427. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  6428. ids=IDS_ONE_TAB;
  6429. else
  6430. ids=0;
  6431. //format the alternative name
  6432. if(!FormatAltNameInfo(dwCertEncodingType,
  6433. dwFormatType,
  6434. dwFormatStrType,
  6435. pFormatStruct,
  6436. ids,
  6437. FALSE,
  6438. &(pInfo->AuthorityCertIssuer),
  6439. NULL,
  6440. &cbNeeded))
  6441. goto FormatAltNameError;
  6442. pwszCertIssuer=(LPWSTR)malloc(cbNeeded);
  6443. if(NULL==pwszCertIssuer)
  6444. goto MemoryError;
  6445. if(!FormatAltNameInfo(dwCertEncodingType,
  6446. dwFormatType,
  6447. dwFormatStrType,
  6448. pFormatStruct,
  6449. ids,
  6450. FALSE,
  6451. &(pInfo->AuthorityCertIssuer),
  6452. pwszCertIssuer,
  6453. &cbNeeded))
  6454. goto FormatAltNameError;
  6455. //format the element. Has to distinguish between the multi line
  6456. //and single line for alternative name:
  6457. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  6458. {
  6459. if(!FormatMessageUnicode(&pwszCertIssuerFormat, IDS_AUTH_CERT_ISSUER_MULTI,pwszCertIssuer))
  6460. goto FormatMsgError;
  6461. }
  6462. else
  6463. {
  6464. if(!FormatMessageUnicode(&pwszCertIssuerFormat, IDS_AUTH_CERT_ISSUER,pwszCertIssuer))
  6465. goto FormatMsgError;
  6466. }
  6467. #if (0) // DSIE: Bug 27436
  6468. pwsz=(LPWSTR)realloc(pwsz,
  6469. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)
  6470. +wcslen(pwszCertIssuerFormat)+1));
  6471. if(NULL==pwsz)
  6472. goto MemoryError;
  6473. #endif
  6474. pwszTemp=(LPWSTR)realloc(pwsz,
  6475. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)
  6476. +wcslen(pwszCertIssuerFormat)+1));
  6477. if(NULL==pwszTemp)
  6478. goto MemoryError;
  6479. pwsz = pwszTemp;
  6480. wcscat(pwsz,pwszCertIssuerFormat);
  6481. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  6482. wcscat(pwsz, wszCRLF);
  6483. }
  6484. //format CertSerialNumber
  6485. if(0!=pInfo->AuthorityCertSerialNumber.cbData)
  6486. {
  6487. //strcat ", " if there is data before
  6488. if(0!=wcslen(pwsz))
  6489. {
  6490. if(0==(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
  6491. wcscat(pwsz, wszCOMMA);
  6492. }
  6493. //copy the serial number into the correct order
  6494. pByte=(BYTE *)malloc(pInfo->AuthorityCertSerialNumber.cbData);
  6495. if(NULL==pByte)
  6496. goto MemoryError;
  6497. for(dwByteIndex=0; dwByteIndex <pInfo->AuthorityCertSerialNumber.cbData;
  6498. dwByteIndex++)
  6499. {
  6500. pByte[dwByteIndex]=*(pInfo->AuthorityCertSerialNumber.pbData+
  6501. pInfo->AuthorityCertSerialNumber.cbData-1-dwByteIndex);
  6502. }
  6503. cbNeeded=0;
  6504. if(!FormatBytesToHex(dwCertEncodingType,
  6505. dwFormatType,
  6506. dwFormatStrType,
  6507. NULL,
  6508. NULL,
  6509. pByte,
  6510. pInfo->AuthorityCertSerialNumber.cbData,
  6511. NULL,
  6512. &cbNeeded))
  6513. goto CertNumberBytesToHexError;
  6514. pwszCertNumber=(LPWSTR)malloc(cbNeeded);
  6515. if(NULL==pwszCertNumber)
  6516. goto MemoryError;
  6517. if(!FormatBytesToHex(dwCertEncodingType,
  6518. dwFormatType,
  6519. dwFormatStrType,
  6520. NULL,
  6521. NULL,
  6522. pByte,
  6523. pInfo->AuthorityCertSerialNumber.cbData,
  6524. pwszCertNumber,
  6525. &cbNeeded))
  6526. goto CertNumberBytesToHexError;
  6527. if(!FormatMessageUnicode(&pwszCertNumberFormat, IDS_AUTH_CERT_NUMBER,pwszCertNumber))
  6528. goto FormatMsgError;
  6529. #if (0) // DSIE: Bug 27436
  6530. pwsz=(LPWSTR)realloc(pwsz,
  6531. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)
  6532. +wcslen(pwszCertNumberFormat)+1));
  6533. if(NULL==pwsz)
  6534. goto MemoryError;
  6535. #endif
  6536. pwszTemp=(LPWSTR)realloc(pwsz,
  6537. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)
  6538. +wcslen(pwszCertNumberFormat)+1));
  6539. if(NULL==pwszTemp)
  6540. goto MemoryError;
  6541. pwsz = pwszTemp;
  6542. wcscat(pwsz,pwszCertNumberFormat);
  6543. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  6544. wcscat(pwsz, wszCRLF);
  6545. }
  6546. //convert the WCHAR version
  6547. pwszFormat=pwsz;
  6548. }
  6549. cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
  6550. //length only calculation
  6551. if(NULL==pbFormat)
  6552. {
  6553. *pcbFormat=cbNeeded;
  6554. fResult=TRUE;
  6555. goto CommonReturn;
  6556. }
  6557. if((*pcbFormat)<cbNeeded)
  6558. {
  6559. *pcbFormat=cbNeeded;
  6560. goto MoreDataError;
  6561. }
  6562. //copy the data
  6563. memcpy(pbFormat, pwszFormat, cbNeeded);
  6564. //copy the size
  6565. *pcbFormat=cbNeeded;
  6566. fResult=TRUE;
  6567. CommonReturn:
  6568. if(pByte)
  6569. free(pByte);
  6570. if(pwszKeyID)
  6571. free(pwszKeyID);
  6572. if(pwszKeyIDFormat)
  6573. LocalFree((HLOCAL)pwszKeyIDFormat);
  6574. if(pwszCertIssuer)
  6575. free(pwszCertIssuer);
  6576. if(pwszCertIssuerFormat)
  6577. LocalFree((HLOCAL)pwszCertIssuerFormat);
  6578. if(pwszCertNumber)
  6579. free(pwszCertNumber);
  6580. if(pwszCertNumberFormat)
  6581. LocalFree((HLOCAL)pwszCertNumberFormat);
  6582. if(pwsz)
  6583. free(pwsz);
  6584. if(pInfo)
  6585. free(pInfo);
  6586. return fResult;
  6587. ErrorReturn:
  6588. fResult=FALSE;
  6589. goto CommonReturn;
  6590. SET_ERROR(InvalidArg, E_INVALIDARG);
  6591. TRACE_ERROR(DecodeGenericError);
  6592. TRACE_ERROR(LoadStringError);
  6593. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  6594. TRACE_ERROR(FormatMsgError);
  6595. TRACE_ERROR(KeyIDBytesToHexError);
  6596. TRACE_ERROR(FormatAltNameError);
  6597. TRACE_ERROR(CertNumberBytesToHexError);
  6598. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  6599. }
  6600. //--------------------------------------------------------------------------
  6601. //
  6602. // FormatBasicConstraints: szOID_BASIC_CONSTRAINTS
  6603. // X509_BASIC_CONSTRAINTS
  6604. //--------------------------------------------------------------------------
  6605. static BOOL
  6606. WINAPI
  6607. FormatBasicConstraints(
  6608. DWORD dwCertEncodingType,
  6609. DWORD dwFormatType,
  6610. DWORD dwFormatStrType,
  6611. void *pFormatStruct,
  6612. LPCSTR lpszStructType,
  6613. const BYTE *pbEncoded,
  6614. DWORD cbEncoded,
  6615. void *pbFormat,
  6616. DWORD *pcbFormat)
  6617. {
  6618. LPWSTR pwszFormat=NULL;
  6619. WCHAR wszSubject[SUBJECT_SIZE * 2];
  6620. WCHAR wszNone[NONE_SIZE];
  6621. LPWSTR pwszFormatSub=NULL;
  6622. LPWSTR pwszFormatWhole=NULL;
  6623. LPWSTR pwszSubtreeName=NULL;
  6624. LPWSTR pwszSubtreeFormat=NULL;
  6625. DWORD dwIndex=0;
  6626. PCERT_BASIC_CONSTRAINTS_INFO pInfo=NULL;
  6627. DWORD cbNeeded=0;
  6628. BOOL fResult=FALSE;
  6629. UINT idsSub=0;
  6630. LPWSTR pwszTemp;
  6631. //check for input parameters
  6632. if((NULL==pbEncoded&& cbEncoded!=0) ||
  6633. (NULL==pcbFormat))
  6634. goto InvalidArg;
  6635. if(cbEncoded==0)
  6636. {
  6637. *pcbFormat=0;
  6638. goto InvalidArg;
  6639. }
  6640. if (!DecodeGenericBLOB(dwCertEncodingType,X509_BASIC_CONSTRAINTS,
  6641. pbEncoded,cbEncoded, (void **)&pInfo))
  6642. goto DecodeGenericError;
  6643. //load the string for the subjectType
  6644. //init to "\0"
  6645. *wszSubject=L'\0';
  6646. if(0!=pInfo->SubjectType.cbData)
  6647. {
  6648. //get the subjectType info
  6649. if ((pInfo->SubjectType.pbData[0]) & CERT_CA_SUBJECT_FLAG)
  6650. {
  6651. if(!LoadStringU(hFrmtFuncInst,IDS_SUB_CA, wszSubject, sizeof(wszSubject)/sizeof(wszSubject[0])))
  6652. goto LoadStringError;
  6653. }
  6654. if ((pInfo->SubjectType.pbData[0]) & CERT_END_ENTITY_SUBJECT_FLAG)
  6655. {
  6656. if(wcslen(wszSubject)!=0)
  6657. {
  6658. wcscat(wszSubject, wszCOMMA);
  6659. }
  6660. if(!LoadStringU(hFrmtFuncInst,IDS_SUB_EE, wszSubject+wcslen(wszSubject),
  6661. SUBJECT_SIZE))
  6662. goto LoadStringError;
  6663. }
  6664. //load string "NONE"
  6665. if(0==wcslen(wszSubject))
  6666. {
  6667. if(!LoadStringU(hFrmtFuncInst,IDS_NONE, wszSubject, sizeof(wszSubject)/sizeof(wszSubject[0])))
  6668. goto LoadStringError;
  6669. }
  6670. }
  6671. //path contraints
  6672. if (pInfo->fPathLenConstraint)
  6673. {
  6674. //decide between single line and mulitple line format
  6675. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  6676. idsSub=IDS_BASIC_CONS2_PATH_MULTI;
  6677. else
  6678. idsSub=IDS_BASIC_CONS2_PATH;
  6679. if(!FormatMessageUnicode(&pwszFormatSub,idsSub,
  6680. wszSubject, pInfo->dwPathLenConstraint))
  6681. goto FormatMsgError;
  6682. }
  6683. else
  6684. {
  6685. if(!LoadStringU(hFrmtFuncInst,IDS_NONE, wszNone, sizeof(wszNone)/sizeof(wszNone[0])))
  6686. goto LoadStringError;
  6687. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  6688. idsSub=IDS_BASIC_CONS2_NONE_MULTI;
  6689. else
  6690. idsSub=IDS_BASIC_CONS2_NONE;
  6691. if(!FormatMessageUnicode(&pwszFormatSub,idsSub,
  6692. wszSubject, wszNone))
  6693. goto FormatMsgError;
  6694. }
  6695. pwszFormatWhole=(LPWSTR)malloc(sizeof(WCHAR) * (wcslen(pwszFormatSub)+1));
  6696. if(!pwszFormatWhole)
  6697. goto MemoryError;
  6698. wcscpy(pwszFormatWhole, pwszFormatSub);
  6699. //now, format SubTreeContraints one at a time
  6700. for(dwIndex=0; dwIndex<pInfo->cSubtreesConstraint; dwIndex++)
  6701. {
  6702. //get WCHAR version of the name
  6703. if(!CryptDllFormatNameAll(
  6704. dwCertEncodingType,
  6705. dwFormatType,
  6706. dwFormatStrType,
  6707. pFormatStruct,
  6708. IDS_ONE_TAB,
  6709. TRUE, //memory allocation
  6710. pInfo->rgSubtreesConstraint[dwIndex].pbData,
  6711. pInfo->rgSubtreesConstraint[dwIndex].cbData,
  6712. (void **)&pwszSubtreeName,
  6713. NULL))
  6714. goto GetCertNameError;
  6715. //decide between single line and mulitple line format
  6716. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  6717. idsSub=IDS_SUBTREE_CONSTRAINT_MULTI;
  6718. else
  6719. idsSub=IDS_SUBTREE_CONSTRAINT;
  6720. if(!FormatMessageUnicode(&pwszSubtreeFormat,idsSub,
  6721. dwIndex+1, pwszSubtreeName))
  6722. goto FormatNameError;
  6723. #if (0) // DSIE: Bug 27436
  6724. pwszFormatWhole=(LPWSTR)realloc(pwszFormatWhole,
  6725. sizeof(WCHAR) * (wcslen(pwszFormatWhole)+1+wcslen(pwszSubtreeFormat)));
  6726. if(NULL == pwszFormatWhole)
  6727. goto MemoryError;
  6728. #endif
  6729. pwszTemp=(LPWSTR)realloc(pwszFormatWhole,
  6730. sizeof(WCHAR) * (wcslen(pwszFormatWhole)+1+wcslen(pwszSubtreeFormat)));
  6731. if(NULL == pwszTemp)
  6732. goto MemoryError;
  6733. pwszFormatWhole = pwszTemp;
  6734. wcscat(pwszFormatWhole,pwszSubtreeFormat);
  6735. LocalFree((HLOCAL)pwszSubtreeFormat);
  6736. pwszSubtreeFormat=NULL;
  6737. free(pwszSubtreeName);
  6738. pwszSubtreeName=NULL;
  6739. }
  6740. //format to the wide char version
  6741. pwszFormat=pwszFormatWhole;
  6742. cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
  6743. //length only calculation
  6744. if(NULL==pbFormat)
  6745. {
  6746. *pcbFormat=cbNeeded;
  6747. fResult=TRUE;
  6748. goto CommonReturn;
  6749. }
  6750. if((*pcbFormat)<cbNeeded)
  6751. {
  6752. *pcbFormat=cbNeeded;
  6753. goto MoreDataError;
  6754. }
  6755. //copy the data
  6756. memcpy(pbFormat, pwszFormat, cbNeeded);
  6757. //copy the size
  6758. *pcbFormat=cbNeeded;
  6759. fResult=TRUE;
  6760. CommonReturn:
  6761. if(pwszFormatSub)
  6762. LocalFree((HLOCAL)pwszFormatSub);
  6763. if(pwszSubtreeFormat)
  6764. LocalFree((HLOCAL)pwszSubtreeFormat);
  6765. if(pwszFormatWhole)
  6766. free(pwszFormatWhole);
  6767. if(pwszSubtreeName)
  6768. free(pwszSubtreeName);
  6769. if(pInfo)
  6770. free(pInfo);
  6771. return fResult;
  6772. ErrorReturn:
  6773. fResult=FALSE;
  6774. goto CommonReturn;
  6775. SET_ERROR(InvalidArg, E_INVALIDARG);
  6776. TRACE_ERROR(DecodeGenericError);
  6777. TRACE_ERROR(LoadStringError);
  6778. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  6779. TRACE_ERROR(FormatMsgError);
  6780. TRACE_ERROR(FormatNameError);
  6781. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  6782. TRACE_ERROR(GetCertNameError);
  6783. }
  6784. //--------------------------------------------------------------------------
  6785. //
  6786. // FormatCRLReasonCode:szOID_CRL_REASON_CODE
  6787. // X509_CRL_REASON_CODE
  6788. //--------------------------------------------------------------------------
  6789. static BOOL
  6790. WINAPI
  6791. FormatCRLReasonCode(
  6792. DWORD dwCertEncodingType,
  6793. DWORD dwFormatType,
  6794. DWORD dwFormatStrType,
  6795. void *pFormatStruct,
  6796. LPCSTR lpszStructType,
  6797. const BYTE *pbEncoded,
  6798. DWORD cbEncoded,
  6799. void *pbFormat,
  6800. DWORD *pcbFormat)
  6801. {
  6802. WCHAR wszReason[CRL_REASON_SIZE];
  6803. LPWSTR pwszFormat=NULL;
  6804. int *pInfo=NULL;
  6805. DWORD cbNeeded=0;
  6806. BOOL fResult=FALSE;
  6807. UINT idsCRLReason=0;
  6808. //check for input parameters
  6809. if((NULL==pbEncoded&& cbEncoded!=0) ||
  6810. (NULL==pcbFormat))
  6811. goto InvalidArg;
  6812. if(cbEncoded==0)
  6813. {
  6814. *pcbFormat=0;
  6815. goto InvalidArg;
  6816. }
  6817. if (!DecodeGenericBLOB(dwCertEncodingType,X509_CRL_REASON_CODE,
  6818. pbEncoded,cbEncoded, (void **)&pInfo))
  6819. goto DecodeGenericError;
  6820. //decide which ids to use
  6821. switch(*pInfo)
  6822. {
  6823. case CRL_REASON_UNSPECIFIED:
  6824. idsCRLReason=IDS_UNSPECIFIED;
  6825. break;
  6826. case CRL_REASON_KEY_COMPROMISE:
  6827. idsCRLReason=IDS_KEY_COMPROMISE;
  6828. break;
  6829. case CRL_REASON_CA_COMPROMISE:
  6830. idsCRLReason=IDS_CA_COMPROMISE;
  6831. break;
  6832. case CRL_REASON_AFFILIATION_CHANGED:
  6833. idsCRLReason=IDS_AFFILIATION_CHANGED;
  6834. break;
  6835. case CRL_REASON_SUPERSEDED:
  6836. idsCRLReason=IDS_SUPERSEDED;
  6837. break;
  6838. case CRL_REASON_CESSATION_OF_OPERATION:
  6839. idsCRLReason=IDS_CESSATION_OF_OPERATION;
  6840. break;
  6841. case CRL_REASON_CERTIFICATE_HOLD:
  6842. idsCRLReason=IDS_CERTIFICATE_HOLD;
  6843. break;
  6844. case CRL_REASON_REMOVE_FROM_CRL:
  6845. idsCRLReason=IDS_REMOVE_FROM_CRL;
  6846. break;
  6847. default:
  6848. idsCRLReason=IDS_UNKNOWN_CRL_REASON;
  6849. break;
  6850. }
  6851. //load string
  6852. if(!LoadStringU(hFrmtFuncInst,idsCRLReason, wszReason, sizeof(wszReason)/sizeof(wszReason[0])))
  6853. goto LoadStringError;
  6854. //format
  6855. if(!FormatMessageUnicode(&pwszFormat, IDS_CRL_REASON, wszReason, *pInfo))
  6856. goto FormatMsgError;
  6857. cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
  6858. //length only calculation
  6859. if(NULL==pbFormat)
  6860. {
  6861. *pcbFormat=cbNeeded;
  6862. fResult=TRUE;
  6863. goto CommonReturn;
  6864. }
  6865. if((*pcbFormat)<cbNeeded)
  6866. {
  6867. *pcbFormat=cbNeeded;
  6868. goto MoreDataError;
  6869. }
  6870. //copy the data
  6871. memcpy(pbFormat, pwszFormat, cbNeeded);
  6872. //copy the size
  6873. *pcbFormat=cbNeeded;
  6874. fResult=TRUE;
  6875. CommonReturn:
  6876. if(pwszFormat)
  6877. LocalFree((HLOCAL)pwszFormat);
  6878. if(pInfo)
  6879. free(pInfo);
  6880. return fResult;
  6881. ErrorReturn:
  6882. fResult=FALSE;
  6883. goto CommonReturn;
  6884. SET_ERROR(InvalidArg, E_INVALIDARG);
  6885. TRACE_ERROR(DecodeGenericError);
  6886. TRACE_ERROR(LoadStringError);
  6887. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  6888. TRACE_ERROR(FormatMsgError);
  6889. }
  6890. //--------------------------------------------------------------------------
  6891. //
  6892. // FormatEnhancedKeyUsage: szOID_ENHANCED_KEY_USAGE
  6893. // X509_ENHANCED_KEY_USAGE
  6894. //--------------------------------------------------------------------------
  6895. static BOOL
  6896. WINAPI
  6897. FormatEnhancedKeyUsage(
  6898. DWORD dwCertEncodingType,
  6899. DWORD dwFormatType,
  6900. DWORD dwFormatStrType,
  6901. void *pFormatStruct,
  6902. LPCSTR lpszStructType,
  6903. const BYTE *pbEncoded,
  6904. DWORD cbEncoded,
  6905. void *pbFormat,
  6906. DWORD *pcbFormat)
  6907. {
  6908. BOOL fOIDNameAllocated=FALSE;
  6909. WCHAR wszNoInfo[NO_INFO_SIZE];
  6910. WCHAR wszUnknownOID[UNKNOWN_KEY_USAGE_SIZE];
  6911. PCCRYPT_OID_INFO pOIDInfo=NULL;
  6912. LPWSTR pwszFormat=NULL;
  6913. LPWSTR pwszOIDName=NULL;
  6914. PCERT_ENHKEY_USAGE pInfo=NULL;
  6915. LPWSTR pwsz=NULL;
  6916. LPWSTR pwszOIDFormat=NULL;
  6917. DWORD dwIndex=0;
  6918. DWORD cbNeeded=0;
  6919. BOOL fResult=FALSE;
  6920. LPWSTR pwszTemp;
  6921. //check for input parameters
  6922. if((NULL==pbEncoded&& cbEncoded!=0) ||
  6923. (NULL==pcbFormat))
  6924. goto InvalidArg;
  6925. if(cbEncoded==0)
  6926. {
  6927. *pcbFormat=0;
  6928. goto InvalidArg;
  6929. }
  6930. if (!DecodeGenericBLOB(dwCertEncodingType,X509_ENHANCED_KEY_USAGE,
  6931. pbEncoded,cbEncoded, (void **)&pInfo))
  6932. goto DecodeGenericError;
  6933. //load string NONE if there is no value available
  6934. if(0==pInfo->cUsageIdentifier)
  6935. {
  6936. if(!LoadStringU(hFrmtFuncInst,IDS_NO_INFO, wszNoInfo, sizeof(wszNoInfo)/sizeof(wszNoInfo[0])))
  6937. goto LoadStringError;
  6938. pwszFormat=wszNoInfo;
  6939. }
  6940. else
  6941. {
  6942. //load the string for "unknown key usage"
  6943. if(!LoadStringU(hFrmtFuncInst,IDS_UNKNOWN_KEY_USAGE, wszUnknownOID,
  6944. sizeof(wszUnknownOID)/sizeof(wszUnknownOID[0])))
  6945. goto LoadStringError;
  6946. pwsz=(LPWSTR)malloc(sizeof(WCHAR));
  6947. if(NULL==pwsz)
  6948. goto MemoryError;
  6949. *pwsz=L'\0';
  6950. //build the comma/\n seperated string
  6951. for(dwIndex=0; dwIndex<pInfo->cUsageIdentifier; dwIndex++)
  6952. {
  6953. fOIDNameAllocated=FALSE;
  6954. pOIDInfo=CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
  6955. (void *)(pInfo->rgpszUsageIdentifier[dwIndex]),
  6956. CRYPT_ENHKEY_USAGE_OID_GROUP_ID);
  6957. if(pOIDInfo)
  6958. {
  6959. //allocate memory, including the NULL terminator
  6960. pwszOIDName=(LPWSTR)malloc((wcslen(pOIDInfo->pwszName)+1)*
  6961. sizeof(WCHAR));
  6962. if(NULL==pwszOIDName)
  6963. goto MemoryError;
  6964. fOIDNameAllocated=TRUE;
  6965. wcscpy(pwszOIDName,pOIDInfo->pwszName);
  6966. }else
  6967. pwszOIDName=wszUnknownOID;
  6968. if(!FormatMessageUnicode(&pwszOIDFormat, IDS_ENHANCED_KEY_USAGE, pwszOIDName,
  6969. (pInfo->rgpszUsageIdentifier)[dwIndex]))
  6970. goto FormatMsgError;
  6971. #if (0) // DSIE: Bug 27436
  6972. pwsz=(LPWSTR)realloc(pwsz,
  6973. sizeof(WCHAR) * (wcslen(pwsz)+
  6974. wcslen(wszCOMMA)+wcslen(pwszOIDFormat)+1));
  6975. if(NULL==pwsz)
  6976. goto MemoryError;
  6977. #endif
  6978. pwszTemp=(LPWSTR)realloc(pwsz,
  6979. sizeof(WCHAR) * (wcslen(pwsz)+
  6980. wcslen(wszCOMMA)+wcslen(pwszOIDFormat)+1));
  6981. if(NULL==pwszTemp)
  6982. goto MemoryError;
  6983. pwsz = pwszTemp;
  6984. //strcat the OID
  6985. wcscat(pwsz, pwszOIDFormat);
  6986. //strcat the , or '\n'
  6987. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  6988. wcscat(pwsz, wszCRLF);
  6989. else
  6990. {
  6991. if(dwIndex!=(pInfo->cUsageIdentifier-1))
  6992. wcscat(pwsz, wszCOMMA);
  6993. }
  6994. LocalFree((HLOCAL)pwszOIDFormat);
  6995. pwszOIDFormat=NULL;
  6996. if(fOIDNameAllocated)
  6997. free(pwszOIDName);
  6998. pwszOIDName=NULL;
  6999. }
  7000. pwszFormat=pwsz;
  7001. }
  7002. cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
  7003. //length only calculation
  7004. if(NULL==pbFormat)
  7005. {
  7006. *pcbFormat=cbNeeded;
  7007. fResult=TRUE;
  7008. goto CommonReturn;
  7009. }
  7010. if((*pcbFormat)<cbNeeded)
  7011. {
  7012. *pcbFormat=cbNeeded;
  7013. goto MoreDataError;
  7014. }
  7015. //copy the data
  7016. memcpy(pbFormat, pwszFormat, cbNeeded);
  7017. //copy the size
  7018. *pcbFormat=cbNeeded;
  7019. fResult=TRUE;
  7020. CommonReturn:
  7021. if(pwsz)
  7022. free(pwsz);
  7023. if(pwszOIDFormat)
  7024. LocalFree((HLOCAL)pwszOIDFormat);
  7025. if(fOIDNameAllocated)
  7026. {
  7027. if(pwszOIDName)
  7028. free(pwszOIDName);
  7029. }
  7030. if(pInfo)
  7031. free(pInfo);
  7032. return fResult;
  7033. ErrorReturn:
  7034. fResult=FALSE;
  7035. goto CommonReturn;
  7036. SET_ERROR(InvalidArg, E_INVALIDARG);
  7037. TRACE_ERROR(DecodeGenericError);
  7038. TRACE_ERROR(LoadStringError);
  7039. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  7040. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  7041. TRACE_ERROR(FormatMsgError);
  7042. }
  7043. //--------------------------------------------------------------------------
  7044. //
  7045. // GetOtherName:
  7046. //
  7047. // The idsPreFix is for multi line formatting only.
  7048. // It should never be 0.
  7049. //--------------------------------------------------------------------------
  7050. BOOL GetOtherName( DWORD dwCertEncodingType,
  7051. DWORD dwFormatType,
  7052. DWORD dwFormatStrType,
  7053. void *pFormatStruct,
  7054. CERT_OTHER_NAME *pOtherName,
  7055. UINT idsPreFix,
  7056. LPWSTR *ppwszOtherName)
  7057. {
  7058. BOOL fResult=FALSE;
  7059. PCCRYPT_OID_INFO pOIDInfo=NULL;
  7060. DWORD cbSize=0;
  7061. WCHAR wszPreFix[PREFIX_SIZE];
  7062. LPWSTR pwszObjId = NULL;
  7063. LPWSTR pwszName=NULL;
  7064. LPWSTR pwszFormat=NULL;
  7065. if(NULL == pOtherName || NULL == ppwszOtherName)
  7066. goto InvalidArg;
  7067. *ppwszOtherName=NULL;
  7068. //get the OID name
  7069. pOIDInfo=CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
  7070. pOtherName->pszObjId,
  7071. 0);
  7072. //get the value. If OID is szOID_NT_PRINCIPAL_NAME, we format it
  7073. //as the unicode string. Otherwise, we hex dump
  7074. if(0 == strcmp(szOID_NT_PRINCIPAL_NAME, pOtherName->pszObjId))
  7075. {
  7076. //turn off the multi line here
  7077. if(!FormatAnyUnicodeStringExtension(
  7078. dwCertEncodingType,
  7079. dwFormatType,
  7080. dwFormatStrType & (~CRYPT_FORMAT_STR_MULTI_LINE),
  7081. pFormatStruct,
  7082. pOtherName->pszObjId,
  7083. pOtherName->Value.pbData,
  7084. pOtherName->Value.cbData,
  7085. NULL,
  7086. &cbSize))
  7087. goto FormatUnicodeError;
  7088. pwszName=(LPWSTR)malloc(cbSize);
  7089. if(NULL==pwszName)
  7090. goto MemoryError;
  7091. if(!FormatAnyUnicodeStringExtension(
  7092. dwCertEncodingType,
  7093. dwFormatType,
  7094. dwFormatStrType & (~CRYPT_FORMAT_STR_MULTI_LINE),
  7095. pFormatStruct,
  7096. pOtherName->pszObjId,
  7097. pOtherName->Value.pbData,
  7098. pOtherName->Value.cbData,
  7099. pwszName,
  7100. &cbSize))
  7101. goto FormatUnicodeError;
  7102. }
  7103. else
  7104. {
  7105. if(!FormatBytesToHex(dwCertEncodingType,
  7106. dwFormatType,
  7107. dwFormatStrType & (~CRYPT_FORMAT_STR_MULTI_LINE),
  7108. pFormatStruct,
  7109. NULL,
  7110. pOtherName->Value.pbData,
  7111. pOtherName->Value.cbData,
  7112. NULL,
  7113. &cbSize))
  7114. goto FormatByesToHexError;
  7115. pwszName=(LPWSTR)malloc(cbSize);
  7116. if(NULL==pwszName)
  7117. goto MemoryError;
  7118. if(!FormatBytesToHex(dwCertEncodingType,
  7119. dwFormatType,
  7120. dwFormatStrType & (~CRYPT_FORMAT_STR_MULTI_LINE),
  7121. pFormatStruct,
  7122. NULL,
  7123. pOtherName->Value.pbData,
  7124. pOtherName->Value.cbData,
  7125. pwszName,
  7126. &cbSize))
  7127. goto FormatByesToHexError;
  7128. }
  7129. if(pOIDInfo)
  7130. {
  7131. if(!FormatMessageUnicode(&pwszFormat,
  7132. IDS_OTHER_NAME_OIDNAME,
  7133. pOIDInfo->pwszName,
  7134. pwszName))
  7135. goto FormatMsgError;
  7136. }
  7137. else
  7138. {
  7139. //
  7140. // Convert OID to Unicode.
  7141. //
  7142. if (!AllocateAnsiToUnicode(pOtherName->pszObjId, &pwszObjId))
  7143. goto AnsiToUnicodeError;
  7144. if(!FormatMessageUnicode(&pwszFormat,IDS_OTHER_NAME_OID, pwszObjId, pwszName))
  7145. goto FormatMsgError;
  7146. }
  7147. //copy the prefix and content
  7148. if(!LoadStringU(hFrmtFuncInst,idsPreFix, wszPreFix, sizeof(wszPreFix)/sizeof(wszPreFix[0])))
  7149. goto LoadStringError;
  7150. *ppwszOtherName=(LPWSTR)malloc(sizeof(WCHAR) * (wcslen(wszPreFix) + wcslen(pwszFormat) + 1));
  7151. if(NULL == *ppwszOtherName)
  7152. goto MemoryError;
  7153. **ppwszOtherName=L'\0';
  7154. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  7155. wcscat(*ppwszOtherName, wszPreFix);
  7156. wcscat(*ppwszOtherName, pwszFormat);
  7157. fResult=TRUE;
  7158. CommonReturn:
  7159. if (pwszObjId)
  7160. free(pwszObjId);
  7161. if(pwszName)
  7162. free(pwszName);
  7163. if(pwszFormat)
  7164. LocalFree((HLOCAL)pwszFormat);
  7165. return fResult;
  7166. ErrorReturn:
  7167. fResult=FALSE;
  7168. goto CommonReturn;
  7169. SET_ERROR(InvalidArg, E_INVALIDARG);
  7170. TRACE_ERROR(FormatByesToHexError);
  7171. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  7172. TRACE_ERROR(AnsiToUnicodeError);
  7173. TRACE_ERROR(FormatUnicodeError);
  7174. TRACE_ERROR(LoadStringError);
  7175. TRACE_ERROR(FormatMsgError);
  7176. }
  7177. //--------------------------------------------------------------------------
  7178. //
  7179. // FormatAltNameInfo:
  7180. //
  7181. //--------------------------------------------------------------------------
  7182. BOOL FormatAltNameInfo(
  7183. DWORD dwCertEncodingType,
  7184. DWORD dwFormatType,
  7185. DWORD dwFormatStrType,
  7186. void *pFormatStruct,
  7187. UINT idsPreFix,
  7188. BOOL fNewLine,
  7189. PCERT_ALT_NAME_INFO pInfo,
  7190. void *pbFormat,
  7191. DWORD *pcbFormat)
  7192. {
  7193. LPWSTR pwszFormat=NULL;
  7194. LPWSTR pwsz=NULL;
  7195. LPWSTR pwszAltEntryFormat=NULL;
  7196. LPWSTR pwszAltEntry=NULL;
  7197. WCHAR wszNoInfo[NO_INFO_SIZE];
  7198. WCHAR wszAltName[ALT_NAME_SIZE];
  7199. WCHAR wszPreFix[PRE_FIX_SIZE];
  7200. BOOL fEntryAllocated=FALSE;
  7201. DWORD dwIndex=0;
  7202. DWORD cbNeeded=0;
  7203. BOOL fResult=FALSE;
  7204. HRESULT hr=S_OK;
  7205. UINT idsAltEntryName=0;
  7206. LPWSTR pwszTemp;
  7207. //load the string "info not available"
  7208. if(!LoadStringU(hFrmtFuncInst,IDS_NO_ALT_NAME, wszNoInfo, sizeof(wszNoInfo)/sizeof(wszNoInfo[0])))
  7209. goto LoadStringError;
  7210. //build the list of alternative name entries
  7211. //1st, check if any information is available
  7212. if(0==pInfo->cAltEntry)
  7213. {
  7214. pwszFormat=wszNoInfo;
  7215. }
  7216. else
  7217. {
  7218. //load the pre-dix
  7219. if(0!=idsPreFix)
  7220. {
  7221. if(!LoadStringU(hFrmtFuncInst, idsPreFix,
  7222. wszPreFix, sizeof(wszPreFix)/sizeof(wszPreFix[0])))
  7223. goto LoadStringError;
  7224. }
  7225. pwsz=(LPWSTR)malloc(sizeof(WCHAR));
  7226. if(NULL==pwsz)
  7227. goto MemoryError;
  7228. //NULL terminate the string
  7229. *pwsz=L'\0';
  7230. //build the list of alternative name entries
  7231. for(dwIndex=0; dwIndex<pInfo->cAltEntry; dwIndex++)
  7232. {
  7233. // DSIE: Fix bug 128630.
  7234. cbNeeded = 0;
  7235. fEntryAllocated=FALSE;
  7236. switch((pInfo->rgAltEntry)[dwIndex].dwAltNameChoice)
  7237. {
  7238. case CERT_ALT_NAME_OTHER_NAME:
  7239. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  7240. idsAltEntryName=IDS_OTHER_NAME_MULTI;
  7241. else
  7242. idsAltEntryName=IDS_OTHER_NAME;
  7243. if(!GetOtherName(
  7244. dwCertEncodingType,
  7245. dwFormatType,
  7246. dwFormatStrType,
  7247. pFormatStruct,
  7248. (pInfo->rgAltEntry)[dwIndex].pOtherName,
  7249. (0!=idsPreFix) ? idsPreFix+1 : IDS_ONE_TAB,
  7250. &pwszAltEntry))
  7251. goto GetOtherNameError;
  7252. fEntryAllocated=TRUE;
  7253. break;
  7254. case CERT_ALT_NAME_RFC822_NAME:
  7255. idsAltEntryName=IDS_RFC822_NAME;
  7256. pwszAltEntry=(pInfo->rgAltEntry)[dwIndex].pwszRfc822Name;
  7257. break;
  7258. case CERT_ALT_NAME_DNS_NAME:
  7259. idsAltEntryName=IDS_DNS_NAME;
  7260. pwszAltEntry=(pInfo->rgAltEntry)[dwIndex].pwszDNSName;
  7261. break;
  7262. case CERT_ALT_NAME_X400_ADDRESS:
  7263. idsAltEntryName=IDS_X400_ADDRESS;
  7264. pwszAltEntry=wszNoInfo;
  7265. break;
  7266. case CERT_ALT_NAME_DIRECTORY_NAME:
  7267. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  7268. idsAltEntryName=IDS_DIRECTORY_NAME_MULTI;
  7269. else
  7270. idsAltEntryName=IDS_DIRECTORY_NAME;
  7271. if(!CryptDllFormatNameAll(
  7272. dwCertEncodingType,
  7273. dwFormatType,
  7274. dwFormatStrType,
  7275. pFormatStruct,
  7276. (0!=idsPreFix) ? idsPreFix+1 : IDS_ONE_TAB,
  7277. TRUE, //memory allocation
  7278. (pInfo->rgAltEntry)[dwIndex].DirectoryName.pbData,
  7279. (pInfo->rgAltEntry)[dwIndex].DirectoryName.cbData,
  7280. (void **)&pwszAltEntry,
  7281. NULL))
  7282. goto GetCertNameError;
  7283. fEntryAllocated=TRUE;
  7284. break;
  7285. case CERT_ALT_NAME_EDI_PARTY_NAME:
  7286. idsAltEntryName=IDS_EDI_PARTY_NAME;
  7287. pwszAltEntry=wszNoInfo;
  7288. break;
  7289. case CERT_ALT_NAME_URL:
  7290. idsAltEntryName=IDS_URL;
  7291. pwszAltEntry=(pInfo->rgAltEntry)[dwIndex].pwszURL;
  7292. break;
  7293. case CERT_ALT_NAME_IP_ADDRESS:
  7294. idsAltEntryName=IDS_IP_ADDRESS;
  7295. #if (0) // DSIE: 7/25/2000
  7296. if(!FormatBytesToHex(dwCertEncodingType,
  7297. dwFormatType,
  7298. dwFormatStrType,
  7299. pFormatStruct,
  7300. NULL,
  7301. (pInfo->rgAltEntry)[dwIndex].IPAddress.pbData,
  7302. (pInfo->rgAltEntry)[dwIndex].IPAddress.cbData,
  7303. NULL,
  7304. &cbNeeded))
  7305. goto FormatByesToHexError;
  7306. pwszAltEntry=(LPWSTR)malloc(cbNeeded);
  7307. if(NULL==pwszAltEntry)
  7308. goto MemoryError;
  7309. if(!FormatBytesToHex(dwCertEncodingType,
  7310. dwFormatType,
  7311. dwFormatStrType,
  7312. pFormatStruct,
  7313. NULL,
  7314. (pInfo->rgAltEntry)[dwIndex].IPAddress.pbData,
  7315. (pInfo->rgAltEntry)[dwIndex].IPAddress.cbData,
  7316. pwszAltEntry,
  7317. &cbNeeded))
  7318. goto FormatByesToHexError;
  7319. #else
  7320. if (!FormatIPAddress(dwCertEncodingType,
  7321. dwFormatType,
  7322. dwFormatStrType,
  7323. pFormatStruct,
  7324. NULL,
  7325. idsPreFix,
  7326. (pInfo->rgAltEntry)[dwIndex].IPAddress.pbData,
  7327. (pInfo->rgAltEntry)[dwIndex].IPAddress.cbData,
  7328. pwszAltEntry,
  7329. &cbNeeded))
  7330. goto FormatIPAddressError;
  7331. pwszAltEntry=(LPWSTR)malloc(cbNeeded);
  7332. if(NULL==pwszAltEntry)
  7333. goto MemoryError;
  7334. if (!FormatIPAddress(dwCertEncodingType,
  7335. dwFormatType,
  7336. dwFormatStrType,
  7337. pFormatStruct,
  7338. NULL,
  7339. idsPreFix,
  7340. (pInfo->rgAltEntry)[dwIndex].IPAddress.pbData,
  7341. (pInfo->rgAltEntry)[dwIndex].IPAddress.cbData,
  7342. pwszAltEntry,
  7343. &cbNeeded))
  7344. goto FormatIPAddressError;
  7345. #endif
  7346. fEntryAllocated=TRUE;
  7347. break;
  7348. case CERT_ALT_NAME_REGISTERED_ID:
  7349. idsAltEntryName=IDS_REGISTERED_ID;
  7350. if(S_OK!=(hr=SZtoWSZ((pInfo->rgAltEntry)[dwIndex].pszRegisteredID,
  7351. &pwszAltEntry)))
  7352. goto SZtoWSZError;
  7353. fEntryAllocated=TRUE;
  7354. break;
  7355. default:
  7356. idsAltEntryName=IDS_UNKNOWN_VALUE;
  7357. pwszAltEntry=wszNoInfo;
  7358. break;
  7359. }
  7360. //load the alternative name string
  7361. if(!LoadStringU(hFrmtFuncInst,idsAltEntryName, wszAltName, sizeof(wszAltName)/sizeof(wszAltName[0])))
  7362. goto LoadStringError;
  7363. //format message
  7364. if(idsAltEntryName!=IDS_UNKNOWN_VALUE)
  7365. {
  7366. if(!FormatMessageUnicode(&pwszAltEntryFormat,IDS_ALT_NAME_ENTRY, wszAltName,
  7367. pwszAltEntry))
  7368. goto FormatMsgError;
  7369. }
  7370. else
  7371. {
  7372. if(!FormatMessageUnicode(&pwszAltEntryFormat,IDS_ALT_NAME_ENTRY_UNKNOWN, wszAltName,
  7373. (pInfo->rgAltEntry)[dwIndex].dwAltNameChoice))
  7374. goto FormatMsgError;
  7375. }
  7376. //concatenate the string, including the postfix and prefix if necessary
  7377. if(0!=idsPreFix)
  7378. {
  7379. #if (0) // DSIE: Bug 27436
  7380. pwsz=(LPWSTR)realloc(pwsz,
  7381. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(wszPreFix)+wcslen(pwszAltEntryFormat)+1));
  7382. #endif
  7383. pwszTemp=(LPWSTR)realloc(pwsz,
  7384. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(wszPreFix)+wcslen(pwszAltEntryFormat)+1));
  7385. }
  7386. else
  7387. {
  7388. #if (0) // DSIE: Bug 27436
  7389. pwsz=(LPWSTR)realloc(pwsz,
  7390. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszAltEntryFormat)+1));
  7391. #endif
  7392. pwszTemp=(LPWSTR)realloc(pwsz,
  7393. sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszAltEntryFormat)+1));
  7394. }
  7395. #if (0) // DSIE: Bug 27436
  7396. if(NULL==pwsz)
  7397. goto MemoryError;
  7398. #endif
  7399. if(NULL==pwszTemp)
  7400. goto MemoryError;
  7401. pwsz = pwszTemp;
  7402. //strcat the preFix
  7403. if(0!=idsPreFix)
  7404. wcscat(pwsz, wszPreFix);
  7405. //strcat the entry
  7406. wcscat(pwsz, pwszAltEntryFormat);
  7407. //strcat the postFix
  7408. if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
  7409. {
  7410. if((TRUE==fNewLine) || (dwIndex != (pInfo->cAltEntry-1)))
  7411. {
  7412. //no need for \n if the name is directory name (CERT_NAME)
  7413. //in multi line format
  7414. if(idsAltEntryName !=IDS_DIRECTORY_NAME_MULTI)
  7415. wcscat(pwsz, wszCRLF);
  7416. }
  7417. }
  7418. else
  7419. {
  7420. if(dwIndex != (pInfo->cAltEntry-1))
  7421. wcscat(pwsz, wszCOMMA);
  7422. }
  7423. LocalFree((HLOCAL)pwszAltEntryFormat);
  7424. pwszAltEntryFormat=NULL;
  7425. if(fEntryAllocated)
  7426. free(pwszAltEntry);
  7427. pwszAltEntry=NULL;
  7428. }
  7429. //if the last entry in the alternative name is IDS_DIRECTORY_NAME_MULTI,
  7430. //we need to get rid of the last \n if fNewLine is FALSE
  7431. if(FALSE==fNewLine)
  7432. {
  7433. if(idsAltEntryName==IDS_DIRECTORY_NAME_MULTI)
  7434. {
  7435. *(pwsz+wcslen(pwsz)-wcslen(wszCRLF))=L'\0';
  7436. }
  7437. }
  7438. //conver to the WCHAR format
  7439. pwszFormat=pwsz;
  7440. }
  7441. cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
  7442. //length only calculation
  7443. if(NULL==pbFormat)
  7444. {
  7445. *pcbFormat=cbNeeded;
  7446. fResult=TRUE;
  7447. goto CommonReturn;
  7448. }
  7449. if((*pcbFormat)<cbNeeded)
  7450. {
  7451. *pcbFormat=cbNeeded;
  7452. goto MoreDataError;
  7453. }
  7454. //copy the data
  7455. memcpy(pbFormat, pwszFormat, cbNeeded);
  7456. //copy the size
  7457. *pcbFormat=cbNeeded;
  7458. fResult=TRUE;
  7459. CommonReturn:
  7460. if(pwsz)
  7461. free(pwsz);
  7462. if(pwszAltEntryFormat)
  7463. LocalFree((HLOCAL)pwszAltEntryFormat);
  7464. if(fEntryAllocated)
  7465. {
  7466. if(pwszAltEntry)
  7467. free(pwszAltEntry);
  7468. }
  7469. return fResult;
  7470. ErrorReturn:
  7471. fResult=FALSE;
  7472. goto CommonReturn;
  7473. TRACE_ERROR(LoadStringError);
  7474. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  7475. TRACE_ERROR(FormatMsgError);
  7476. SET_ERROR_VAR(SZtoWSZError, hr);
  7477. TRACE_ERROR(GetCertNameError);
  7478. #if (0) //DSIE
  7479. TRACE_ERROR(FormatByesToHexError);
  7480. #else
  7481. TRACE_ERROR(FormatIPAddressError);
  7482. #endif
  7483. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  7484. TRACE_ERROR(GetOtherNameError);
  7485. }
  7486. //--------------------------------------------------------------------------
  7487. //
  7488. // FormatAltName: X509_ALTERNATE_NAME
  7489. // szOID_SUBJECT_ALT_NAME
  7490. // szOID_ISSUER_ALT_NAME
  7491. // szOID_SUBJECT_ALT_NAME2
  7492. // szOID_ISSUER_ALT_NAME2
  7493. //
  7494. //--------------------------------------------------------------------------
  7495. static BOOL
  7496. WINAPI
  7497. FormatAltName(
  7498. DWORD dwCertEncodingType,
  7499. DWORD dwFormatType,
  7500. DWORD dwFormatStrType,
  7501. void *pFormatStruct,
  7502. LPCSTR lpszStructType,
  7503. const BYTE *pbEncoded,
  7504. DWORD cbEncoded,
  7505. void *pbFormat,
  7506. DWORD *pcbFormat)
  7507. {
  7508. BOOL fResult=FALSE;
  7509. PCERT_ALT_NAME_INFO pInfo=NULL;
  7510. //check for input parameters
  7511. if((NULL==pbEncoded&& cbEncoded!=0) ||
  7512. (NULL==pcbFormat))
  7513. goto InvalidArg;
  7514. if(cbEncoded==0)
  7515. {
  7516. *pcbFormat=0;
  7517. goto InvalidArg;
  7518. }
  7519. if (!DecodeGenericBLOB(dwCertEncodingType,X509_ALTERNATE_NAME,
  7520. pbEncoded,cbEncoded, (void **)&pInfo))
  7521. goto DecodeGenericError;
  7522. fResult=FormatAltNameInfo(dwCertEncodingType, dwFormatType,dwFormatStrType,
  7523. pFormatStruct,
  7524. 0,
  7525. TRUE,
  7526. pInfo, pbFormat, pcbFormat);
  7527. if(FALSE==fResult)
  7528. goto FormatAltNameError;
  7529. CommonReturn:
  7530. if(pInfo)
  7531. free(pInfo);
  7532. return fResult;
  7533. ErrorReturn:
  7534. fResult=FALSE;
  7535. goto CommonReturn;
  7536. SET_ERROR(InvalidArg, E_INVALIDARG);
  7537. TRACE_ERROR(DecodeGenericError);
  7538. TRACE_ERROR(FormatAltNameError);
  7539. }
  7540. //--------------------------------------------------------------------------
  7541. //
  7542. // GetCertNameMulti
  7543. //
  7544. // Get the multi line display of the certificate name
  7545. //--------------------------------------------------------------------------
  7546. BOOL GetCertNameMulti(LPWSTR pwszNameStr,
  7547. UINT idsPreFix,
  7548. LPWSTR *ppwsz)
  7549. {
  7550. BOOL fResult=FALSE;
  7551. WCHAR wszPreFix[PRE_FIX_SIZE];
  7552. LPWSTR pwszStart=NULL;
  7553. LPWSTR pwszEnd=NULL;
  7554. DWORD dwCopy=0;
  7555. LPWSTR pwszNameStart=NULL;
  7556. BOOL fDone=FALSE;
  7557. BOOL fInQuote=FALSE;
  7558. LPWSTR pwszTemp;
  7559. //init
  7560. *ppwsz=NULL;
  7561. //load string for the preFix
  7562. if(0!=idsPreFix && 1!=idsPreFix)
  7563. {
  7564. if(!LoadStringU(hFrmtFuncInst, idsPreFix, wszPreFix, PRE_FIX_SIZE))
  7565. goto LoadStringError;
  7566. }
  7567. *ppwsz=(LPWSTR)malloc(sizeof(WCHAR));
  7568. if(NULL==*ppwsz)
  7569. goto MemoryError;
  7570. **ppwsz=L'\0';
  7571. //now, start the search for the symbol '+' or ','
  7572. pwszStart=pwszNameStr;
  7573. pwszEnd=pwszNameStr;
  7574. //parse the whole string
  7575. for(;FALSE==fDone; pwszEnd++)
  7576. {
  7577. //mark fInQuote to TRUE if we are inside " "
  7578. if(L'\"'==*pwszEnd)
  7579. fInQuote=!fInQuote;
  7580. if((L'+'==*pwszEnd) || (L','==*pwszEnd) ||(L'\0'==*pwszEnd))
  7581. {
  7582. //make sure + and ; are not quoted
  7583. if((L'+'==*pwszEnd) || (L','==*pwszEnd))
  7584. {
  7585. if(TRUE==fInQuote)
  7586. continue;
  7587. }
  7588. //skip the leading spaces
  7589. for(;*pwszStart != L'\0'; pwszStart++)
  7590. {
  7591. if(*pwszStart != L' ')
  7592. break;
  7593. }
  7594. //we are done if NULL is reached
  7595. if(L'\0'==*pwszStart)
  7596. break;
  7597. //calculate the length to copy
  7598. dwCopy=(DWORD)(pwszEnd-pwszStart);
  7599. if(0!=idsPreFix && 1!=idsPreFix)
  7600. {
  7601. #if (0) // DSIE: Bug 27436
  7602. *ppwsz=(LPWSTR)realloc(*ppwsz,
  7603. (wcslen(*ppwsz)+dwCopy+wcslen(wszPreFix)+wcslen(wszCRLF)+1)*sizeof(WCHAR));
  7604. #endif
  7605. pwszTemp=(LPWSTR)realloc(*ppwsz,
  7606. (wcslen(*ppwsz)+dwCopy+wcslen(wszPreFix)+wcslen(wszCRLF)+1)*sizeof(WCHAR));
  7607. }
  7608. else
  7609. {
  7610. #if (0) // DSIE: Bug 27436
  7611. *ppwsz=(LPWSTR)realloc(*ppwsz,
  7612. (wcslen(*ppwsz)+dwCopy+wcslen(wszCRLF)+1)*sizeof(WCHAR));
  7613. #endif
  7614. pwszTemp=(LPWSTR)realloc(*ppwsz,
  7615. (wcslen(*ppwsz)+dwCopy+wcslen(wszCRLF)+1)*sizeof(WCHAR));
  7616. }
  7617. #if (0) // DSIE: Bug 27436
  7618. if(NULL == *ppwsz)
  7619. goto MemoryError;
  7620. #endif
  7621. if(NULL == pwszTemp)
  7622. goto MemoryError;
  7623. *ppwsz = pwszTemp;
  7624. //copy the prefix
  7625. if(0!=idsPreFix && 1!=idsPreFix)
  7626. wcscat(*ppwsz, wszPreFix);
  7627. pwszNameStart=(*ppwsz)+wcslen(*ppwsz);
  7628. //copy the string to *ppwsz
  7629. memcpy(pwszNameStart, pwszStart, dwCopy*sizeof(WCHAR));
  7630. pwszNameStart += dwCopy;
  7631. //NULL terminate the string
  7632. *pwszNameStart=L'\0';
  7633. //copy the "\n"
  7634. wcscat(*ppwsz, wszCRLF);
  7635. //reset pwszStart and pwszEnd.
  7636. pwszStart=pwszEnd+1;
  7637. if(L'\0'==*pwszEnd)
  7638. fDone=TRUE;
  7639. }
  7640. }
  7641. fResult=TRUE;
  7642. CommonReturn:
  7643. return fResult;
  7644. ErrorReturn:
  7645. if(*ppwsz)
  7646. {
  7647. free(*ppwsz);
  7648. *ppwsz=NULL;
  7649. }
  7650. fResult=FALSE;
  7651. goto CommonReturn;
  7652. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  7653. TRACE_ERROR(LoadStringError);
  7654. }
  7655. //--------------------------------------------------------------------------
  7656. //
  7657. // FormatMessageUnicode
  7658. //
  7659. //--------------------------------------------------------------------------
  7660. BOOL FormatMessageUnicode(LPWSTR * ppwszFormat, UINT ids, ...)
  7661. {
  7662. // get format string from resources
  7663. WCHAR wszFormat[1000];
  7664. va_list argList;
  7665. DWORD cbMsg=0;
  7666. BOOL fResult=FALSE;
  7667. if(NULL == ppwszFormat)
  7668. goto InvalidArgErr;
  7669. #if (0) //DSIE: Bug 160605
  7670. if(!LoadStringU(hFrmtFuncInst, ids, wszFormat, sizeof(wszFormat)))
  7671. #else
  7672. if(!LoadStringU(hFrmtFuncInst, ids, wszFormat, sizeof(wszFormat) / sizeof(wszFormat[0])))
  7673. #endif
  7674. goto LoadStringError;
  7675. // format message into requested buffer
  7676. va_start(argList, ids);
  7677. cbMsg = FormatMessageU(
  7678. FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
  7679. wszFormat,
  7680. 0, // dwMessageId
  7681. 0, // dwLanguageId
  7682. (LPWSTR) (ppwszFormat),
  7683. 0, // minimum size to allocate
  7684. &argList);
  7685. va_end(argList);
  7686. if(!cbMsg)
  7687. #if (1) // DSIE: Fix bug #128630
  7688. //
  7689. // FormatMessageU() will return 0 byte, if data to be
  7690. // formatted is empty. CertSrv generates extensions
  7691. // with empty data for name constraints, so we need to
  7692. // make sure we return an empty string, "", instead of
  7693. // an error and NULL pointer.
  7694. //
  7695. if (0 == GetLastError())
  7696. {
  7697. if (NULL == (*ppwszFormat = (LPWSTR) LocalAlloc(LPTR, sizeof(WCHAR))))
  7698. goto MemoryError;
  7699. }
  7700. else
  7701. #endif
  7702. goto FormatMessageError;
  7703. fResult=TRUE;
  7704. CommonReturn:
  7705. return fResult;
  7706. ErrorReturn:
  7707. fResult=FALSE;
  7708. goto CommonReturn;
  7709. TRACE_ERROR(LoadStringError);
  7710. TRACE_ERROR(FormatMessageError);
  7711. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  7712. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  7713. }
  7714. //--------------------------------------------------------------------------
  7715. //
  7716. // FormatMessageStr
  7717. //
  7718. //--------------------------------------------------------------------------
  7719. /*BOOL FormatMessageStr(LPSTR *ppszFormat,UINT ids,...)
  7720. {
  7721. // get format string from resources
  7722. CHAR szFormat[1000];
  7723. va_list argList;
  7724. BOOL fResult=FALSE;
  7725. HRESULT hr=S_OK;
  7726. if(!LoadStringA(hFrmtFuncInst, ids, szFormat, sizeof(szFormat)))
  7727. goto LoadStringError;
  7728. // format message into requested buffer
  7729. va_start(argList, ids);
  7730. if(0==FormatMessageA(
  7731. FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
  7732. szFormat,
  7733. 0, // dwMessageId
  7734. 0, // dwLanguageId
  7735. (LPSTR) ppszFormat,
  7736. 0, // minimum size to allocate
  7737. &argList))
  7738. goto FormatMessageError;
  7739. va_end(argList);
  7740. fResult=TRUE;
  7741. CommonReturn:
  7742. return fResult;
  7743. ErrorReturn:
  7744. fResult=FALSE;
  7745. goto CommonReturn;
  7746. TRACE_ERROR(LoadStringError);
  7747. TRACE_ERROR(FormatMessageError);
  7748. } */
  7749. //--------------------------------------------------------------------------
  7750. //
  7751. // Decode a generic BLOB
  7752. //
  7753. //--------------------------------------------------------------------------
  7754. BOOL DecodeGenericBLOB(DWORD dwEncodingType, LPCSTR lpszStructType,
  7755. const BYTE *pbEncoded, DWORD cbEncoded,void **ppStructInfo)
  7756. {
  7757. DWORD cbStructInfo=0;
  7758. //decode the object. No copying
  7759. if(!CryptDecodeObject(dwEncodingType,lpszStructType,pbEncoded, cbEncoded,
  7760. 0,NULL, &cbStructInfo))
  7761. return FALSE;
  7762. *ppStructInfo=malloc(cbStructInfo);
  7763. if(!(*ppStructInfo))
  7764. {
  7765. SetLastError((DWORD) E_OUTOFMEMORY);
  7766. return FALSE;
  7767. }
  7768. return CryptDecodeObject(dwEncodingType,lpszStructType,pbEncoded, cbEncoded,
  7769. 0,*ppStructInfo,&cbStructInfo);
  7770. }
  7771. ////////////////////////////////////////////////////////
  7772. //
  7773. // Convert STR to WSTR
  7774. //
  7775. HRESULT SZtoWSZ(LPSTR szStr,LPWSTR *pwsz)
  7776. {
  7777. DWORD dwSize=0;
  7778. DWORD dwError=0;
  7779. *pwsz=NULL;
  7780. //return NULL
  7781. if(!szStr)
  7782. return S_OK;
  7783. dwSize=MultiByteToWideChar(0, 0,szStr, -1,NULL,0);
  7784. if(dwSize==0)
  7785. {
  7786. dwError=GetLastError();
  7787. return HRESULT_FROM_WIN32(dwError);
  7788. }
  7789. //allocate memory
  7790. *pwsz=(LPWSTR)malloc(dwSize * sizeof(WCHAR));
  7791. if(*pwsz==NULL)
  7792. return E_OUTOFMEMORY;
  7793. if(MultiByteToWideChar(0, 0,szStr, -1,
  7794. *pwsz,dwSize))
  7795. {
  7796. return S_OK;
  7797. }
  7798. else
  7799. {
  7800. free(*pwsz);
  7801. *pwsz=NULL;
  7802. dwError=GetLastError();
  7803. return HRESULT_FROM_WIN32(dwError);
  7804. }
  7805. }
  7806. //--------------------------------------------------------------------------
  7807. //
  7808. // Convert dwFormatType to dwStrType
  7809. //
  7810. //--------------------------------------------------------------------------
  7811. DWORD FormatToStr(DWORD dwFormatType)
  7812. {
  7813. DWORD dwStrType=0;
  7814. //we default to CERT_X500_NAME_STR
  7815. if(0==dwFormatType)
  7816. {
  7817. return CERT_X500_NAME_STR;
  7818. }
  7819. if(dwFormatType & CRYPT_FORMAT_SIMPLE)
  7820. dwStrType |= CERT_SIMPLE_NAME_STR;
  7821. if(dwFormatType & CRYPT_FORMAT_X509)
  7822. dwStrType |= CERT_X500_NAME_STR;
  7823. if(dwFormatType & CRYPT_FORMAT_OID)
  7824. dwStrType |= CERT_OID_NAME_STR;
  7825. if(dwFormatType & CRYPT_FORMAT_RDN_SEMICOLON)
  7826. dwStrType |= CERT_NAME_STR_SEMICOLON_FLAG;
  7827. if(dwFormatType & CRYPT_FORMAT_RDN_CRLF)
  7828. dwStrType |= CERT_NAME_STR_CRLF_FLAG;
  7829. if(dwFormatType & CRYPT_FORMAT_RDN_UNQUOTE)
  7830. dwStrType |= CERT_NAME_STR_NO_QUOTING_FLAG;
  7831. if(dwFormatType & CRYPT_FORMAT_RDN_REVERSE)
  7832. dwStrType |= CERT_NAME_STR_REVERSE_FLAG;
  7833. return dwStrType;
  7834. }
  7835. //+-----------------------------------------------------------------------------
  7836. // Post Win2k.
  7837. //------------------------------------------------------------------------------
  7838. //+-----------------------------------------------------------------------------
  7839. //
  7840. // FormatInteger X509_INTEGER
  7841. //
  7842. //------------------------------------------------------------------------------
  7843. static BOOL
  7844. WINAPI
  7845. FormatInteger (
  7846. DWORD dwCertEncodingType,
  7847. DWORD dwFormatStrType,
  7848. const BYTE *pbEncoded,
  7849. DWORD cbEncoded,
  7850. void *pbFormat,
  7851. DWORD *pcbFormat,
  7852. DWORD ids)
  7853. {
  7854. BOOL fResult;
  7855. DWORD cbNeeded;
  7856. int *pInfo = NULL;
  7857. LPWSTR pwszFormat = NULL;
  7858. BOOL bMultiLines = dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE;
  7859. //
  7860. // Check input parameters.
  7861. //
  7862. if ((NULL == pbEncoded && 0 != cbEncoded) ||
  7863. (NULL == pcbFormat) ||
  7864. (0 == cbEncoded))
  7865. {
  7866. goto InvalidArg;
  7867. }
  7868. //
  7869. // Decode extension.
  7870. //
  7871. if (!DecodeGenericBLOB(dwCertEncodingType,
  7872. X509_INTEGER,
  7873. pbEncoded,
  7874. cbEncoded,
  7875. (void **)&pInfo))
  7876. {
  7877. goto DecodeGenericError;
  7878. }
  7879. //
  7880. // Some extension name=%1!d!%2!s!
  7881. //
  7882. if (!FormatMessageUnicode(&pwszFormat,
  7883. ids,
  7884. *pInfo,
  7885. bMultiLines ? wszCRLF : wszEMPTY))
  7886. {
  7887. goto FormatMessageError;
  7888. }
  7889. //
  7890. // Total length needed.
  7891. //
  7892. cbNeeded = sizeof(WCHAR) * (wcslen(pwszFormat) + 1);
  7893. //
  7894. // length only calculation?
  7895. //
  7896. if (NULL == pbFormat)
  7897. {
  7898. *pcbFormat = cbNeeded;
  7899. goto SuccessReturn;
  7900. }
  7901. //
  7902. // Caller provided us with enough memory?
  7903. //
  7904. if (*pcbFormat < cbNeeded)
  7905. {
  7906. *pcbFormat = cbNeeded;
  7907. goto MoreDataError;
  7908. }
  7909. //
  7910. // Copy size and data.
  7911. //
  7912. memcpy(pbFormat, pwszFormat, cbNeeded);
  7913. *pcbFormat = cbNeeded;
  7914. SuccessReturn:
  7915. fResult = TRUE;
  7916. CommonReturn:
  7917. //
  7918. // Free resources.
  7919. //
  7920. if (pInfo)
  7921. {
  7922. free(pInfo);
  7923. }
  7924. if (pwszFormat)
  7925. {
  7926. LocalFree((HLOCAL) pwszFormat);
  7927. }
  7928. return fResult;
  7929. ErrorReturn:
  7930. fResult=FALSE;
  7931. goto CommonReturn;
  7932. SET_ERROR(InvalidArg,E_INVALIDARG);
  7933. TRACE_ERROR(DecodeGenericError);
  7934. TRACE_ERROR(FormatMessageError);
  7935. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  7936. }
  7937. //+-----------------------------------------------------------------------------
  7938. //
  7939. // FormatCrlNumber szOID_CRL_NUMBER
  7940. // szOID_DELTA_CRL_INDICATOR
  7941. // szOID_CRL_VIRTUAL_BASE
  7942. //
  7943. //------------------------------------------------------------------------------
  7944. static BOOL
  7945. WINAPI
  7946. FormatCrlNumber (
  7947. DWORD dwCertEncodingType,
  7948. DWORD dwFormatType,
  7949. DWORD dwFormatStrType,
  7950. void *pFormatStruct,
  7951. LPCSTR lpszStructType,
  7952. const BYTE *pbEncoded,
  7953. DWORD cbEncoded,
  7954. void *pbFormat,
  7955. DWORD *pcbFormat)
  7956. {
  7957. BOOL fResult;
  7958. DWORD cbNeeded = 0;
  7959. DWORD ids = 0;
  7960. BOOL bMultiLines = dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE;
  7961. //
  7962. // Check input parameters.
  7963. //
  7964. if ((NULL == pbEncoded && 0 != cbEncoded) ||
  7965. (NULL == pcbFormat) || (0 == cbEncoded))
  7966. {
  7967. goto InvalidArg;
  7968. }
  7969. //
  7970. // Decide between single line and mulitple line format.
  7971. //
  7972. if (bMultiLines)
  7973. {
  7974. ids = 0 == strcmp(lpszStructType, szOID_CRL_NUMBER) ? IDS_CRL_NUMBER :
  7975. 0 == strcmp(lpszStructType, szOID_DELTA_CRL_INDICATOR) ? IDS_DELTA_CRL_INDICATOR : IDS_CRL_VIRTUAL_BASE;
  7976. }
  7977. else
  7978. {
  7979. ids = IDS_INTEGER;
  7980. }
  7981. //
  7982. // Decode extension to get length.
  7983. //
  7984. // %1!d!%2!s!
  7985. // CRL Number=%1!d!%2!s!
  7986. // Delta CRL Number=%1!d!%2!s!
  7987. // Virtual Base CRL Number=%1!d!%2!s!
  7988. //
  7989. if (!FormatInteger(dwCertEncodingType,
  7990. dwFormatStrType,
  7991. pbEncoded,
  7992. cbEncoded,
  7993. NULL,
  7994. &cbNeeded,
  7995. ids))
  7996. {
  7997. goto FormatIntegerError;
  7998. }
  7999. //
  8000. // length only calculation?
  8001. //
  8002. if (NULL == pbFormat)
  8003. {
  8004. *pcbFormat = cbNeeded;
  8005. goto SuccessReturn;
  8006. }
  8007. //
  8008. // Caller provided us with enough memory?
  8009. //
  8010. if (*pcbFormat < cbNeeded)
  8011. {
  8012. *pcbFormat = cbNeeded;
  8013. goto MoreDataError;
  8014. }
  8015. //
  8016. // Decode again to get data.
  8017. //
  8018. if (!FormatInteger(dwCertEncodingType,
  8019. dwFormatStrType,
  8020. pbEncoded,
  8021. cbEncoded,
  8022. pbFormat,
  8023. &cbNeeded,
  8024. ids))
  8025. {
  8026. goto FormatIntegerError;
  8027. }
  8028. //
  8029. // Copy size .
  8030. //
  8031. *pcbFormat = cbNeeded;
  8032. SuccessReturn:
  8033. fResult = TRUE;
  8034. CommonReturn:
  8035. return fResult;
  8036. ErrorReturn:
  8037. fResult=FALSE;
  8038. goto CommonReturn;
  8039. SET_ERROR(InvalidArg,E_INVALIDARG);
  8040. TRACE_ERROR(FormatIntegerError);
  8041. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  8042. }
  8043. //+-----------------------------------------------------------------------------
  8044. //
  8045. // FormatCrlNextPublish szOID_CRL_NEXT_PUBLISH
  8046. //
  8047. //------------------------------------------------------------------------------
  8048. static BOOL
  8049. WINAPI
  8050. FormatCrlNextPublish (
  8051. DWORD dwCertEncodingType,
  8052. DWORD dwFormatType,
  8053. DWORD dwFormatStrType,
  8054. void *pFormatStruct,
  8055. LPCSTR lpszStructType,
  8056. const BYTE *pbEncoded,
  8057. DWORD cbEncoded,
  8058. void *pbFormat,
  8059. DWORD *pcbFormat)
  8060. {
  8061. BOOL fResult;
  8062. DWORD cbNeeded = 0;
  8063. FILETIME * pInfo = NULL;
  8064. LPWSTR pwszFileTime = NULL;
  8065. LPWSTR pwszFormat = NULL;
  8066. BOOL bMultiLines = dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE;
  8067. //
  8068. // Check input parameters.
  8069. //
  8070. if ((NULL == pbEncoded && 0 != cbEncoded) ||
  8071. (NULL == pcbFormat) || (0 == cbEncoded))
  8072. {
  8073. goto InvalidArg;
  8074. }
  8075. //
  8076. // Decode extension.
  8077. //
  8078. if (!DecodeGenericBLOB(dwCertEncodingType,
  8079. X509_CHOICE_OF_TIME,
  8080. pbEncoded,
  8081. cbEncoded,
  8082. (void **) &pInfo))
  8083. {
  8084. goto DecodeGenericError;
  8085. }
  8086. //
  8087. // Get formatted date/time.
  8088. //
  8089. if (!FormatFileTime(pInfo, &pwszFileTime))
  8090. {
  8091. goto FormatFileTimeError;
  8092. }
  8093. if (!FormatMessageUnicode(&pwszFormat,
  8094. IDS_STRING,
  8095. pwszFileTime,
  8096. bMultiLines ? wszCRLF : wszEMPTY))
  8097. {
  8098. goto FormatMessageError;
  8099. }
  8100. //
  8101. // Total length needed.
  8102. //
  8103. cbNeeded = sizeof(WCHAR) * (wcslen(pwszFormat) + 1);
  8104. //
  8105. // length only calculation?
  8106. //
  8107. if (NULL == pbFormat)
  8108. {
  8109. *pcbFormat = cbNeeded;
  8110. goto SuccessReturn;
  8111. }
  8112. //
  8113. // Caller provided us with enough memory?
  8114. //
  8115. if (*pcbFormat < cbNeeded)
  8116. {
  8117. *pcbFormat = cbNeeded;
  8118. goto MoreDataError;
  8119. }
  8120. //
  8121. // Copy size and data.
  8122. //
  8123. memcpy(pbFormat, pwszFormat, cbNeeded);
  8124. *pcbFormat = cbNeeded;
  8125. SuccessReturn:
  8126. fResult = TRUE;
  8127. CommonReturn:
  8128. if (pInfo)
  8129. {
  8130. free(pInfo);
  8131. }
  8132. if (pwszFileTime)
  8133. {
  8134. LocalFree((HLOCAL) pwszFileTime);
  8135. }
  8136. if (pwszFormat)
  8137. {
  8138. LocalFree((HLOCAL) pwszFormat);
  8139. }
  8140. return fResult;
  8141. ErrorReturn:
  8142. fResult=FALSE;
  8143. goto CommonReturn;
  8144. SET_ERROR(InvalidArg,E_INVALIDARG);
  8145. TRACE_ERROR(DecodeGenericError);
  8146. TRACE_ERROR(FormatFileTimeError);
  8147. TRACE_ERROR(FormatMessageError);
  8148. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  8149. }
  8150. //+-----------------------------------------------------------------------------
  8151. //
  8152. // FormatIssuingDistPoint X509_ISSUING_DIST_POINT
  8153. // szOID_ISSUING_DIST_POINT
  8154. //
  8155. // typedef struct _CRL_ISSUING_DIST_POINT {
  8156. // CRL_DIST_POINT_NAME DistPointName; // OPTIONAL
  8157. // BOOL fOnlyContainsUserCerts;
  8158. // BOOL fOnlyContainsCACerts;
  8159. // CRYPT_BIT_BLOB OnlySomeReasonFlags; // OPTIONAL
  8160. // BOOL fIndirectCRL;
  8161. // } CRL_ISSUING_DIST_POINT, *PCRL_ISSUING_DIST_POINT;
  8162. //
  8163. // typedef struct _CRL_DIST_POINT_NAME {
  8164. // DWORD dwDistPointNameChoice;
  8165. // union {
  8166. // CERT_ALT_NAME_INFO FullName; // 1
  8167. // // Not implemented IssuerRDN; // 2
  8168. // };
  8169. // } CRL_DIST_POINT_NAME, *PCRL_DIST_POINT_NAME;
  8170. //
  8171. //------------------------------------------------------------------------------
  8172. static BOOL
  8173. WINAPI
  8174. FormatIssuingDistPoint (
  8175. DWORD dwCertEncodingType,
  8176. DWORD dwFormatType,
  8177. DWORD dwFormatStrType,
  8178. void *pFormatStruct,
  8179. LPCSTR lpszStructType,
  8180. const BYTE *pbEncoded,
  8181. DWORD cbEncoded,
  8182. void *pbFormat,
  8183. DWORD *pcbFormat)
  8184. {
  8185. BOOL fResult;
  8186. DWORD cbNeeded = 0;
  8187. DWORD ids = 0;
  8188. WCHAR wszYes[YES_NO_SIZE];
  8189. WCHAR wszNo[YES_NO_SIZE];
  8190. LPWSTR pwszTemp = NULL;
  8191. LPWSTR pwszFormat = NULL;
  8192. LPWSTR pwszPointName = NULL;
  8193. LPWSTR pwszNameFormat = NULL;
  8194. LPWSTR pwszOnlyContainsUserCerts = NULL;
  8195. LPWSTR pwszOnlyContainsCACerts = NULL;
  8196. LPWSTR pwszIndirectCRL = NULL;
  8197. LPWSTR pwszCRLReason=NULL;
  8198. LPWSTR pwszReasonFormat=NULL;
  8199. BOOL bMultiLines = dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE;
  8200. PCRL_ISSUING_DIST_POINT pInfo = NULL;
  8201. //
  8202. // Check input parameters.
  8203. //
  8204. if ((NULL == pbEncoded && 0 != cbEncoded) ||
  8205. (NULL == pcbFormat) || (0 == cbEncoded))
  8206. {
  8207. goto InvalidArg;
  8208. }
  8209. //
  8210. // Decode extension.
  8211. //
  8212. if (!DecodeGenericBLOB(dwCertEncodingType,
  8213. lpszStructType,
  8214. pbEncoded,
  8215. cbEncoded,
  8216. (void **)&pInfo))
  8217. {
  8218. goto DecodeGenericError;
  8219. }
  8220. //
  8221. // Allocate format buffer.
  8222. //
  8223. if (!(pwszFormat = (LPWSTR) malloc(sizeof(WCHAR))))
  8224. {
  8225. goto MemoryError;
  8226. }
  8227. *pwszFormat = L'\0';
  8228. //
  8229. // Format distribution name, if exists.
  8230. //
  8231. if (CRL_DIST_POINT_NO_NAME != pInfo->DistPointName.dwDistPointNameChoice)
  8232. {
  8233. if (!FormatDistPointName(dwCertEncodingType,
  8234. dwFormatType,
  8235. dwFormatStrType,
  8236. pFormatStruct,
  8237. &(pInfo->DistPointName),
  8238. &pwszPointName))
  8239. {
  8240. goto FormatDistPointNameError;
  8241. }
  8242. //
  8243. // Decide between single line and mulitple line format.
  8244. //
  8245. ids = bMultiLines ? IDS_ONLY_SOME_CRL_DIST_NAME_MULTI: IDS_ONLY_SOME_CRL_DIST_NAME;
  8246. if (!FormatMessageUnicode(&pwszNameFormat, ids, pwszPointName))
  8247. {
  8248. goto FormatMessageError;
  8249. }
  8250. //
  8251. // Reallocate and concate to format buffer.
  8252. //
  8253. pwszTemp = (LPWSTR) realloc(pwszFormat, sizeof(WCHAR) * (wcslen(pwszFormat) + wcslen(pwszNameFormat) + 1));
  8254. if (NULL == pwszTemp)
  8255. {
  8256. goto MemoryError;
  8257. }
  8258. pwszFormat = pwszTemp;
  8259. wcscat(pwszFormat, pwszNameFormat);
  8260. LocalFree((HLOCAL) pwszPointName);
  8261. pwszPointName = NULL;
  8262. LocalFree((HLOCAL) pwszNameFormat);
  8263. pwszNameFormat = NULL;
  8264. }
  8265. //
  8266. // Format onlyContainsXXX fields.
  8267. //
  8268. if (!LoadStringU(hFrmtFuncInst,
  8269. IDS_YES,
  8270. wszYes,
  8271. sizeof(wszYes) / sizeof(wszYes[0])))
  8272. {
  8273. goto LoadStringError;
  8274. }
  8275. if (!LoadStringU(hFrmtFuncInst,
  8276. IDS_NO,
  8277. wszNo,
  8278. sizeof(wszNo) / sizeof(wszNo[0])))
  8279. {
  8280. goto LoadStringError;
  8281. }
  8282. //
  8283. // %1!s!Only Contains User Certs=%2!s!%3!s!
  8284. //
  8285. if (!FormatMessageUnicode(&pwszOnlyContainsUserCerts,
  8286. IDS_ONLY_CONTAINS_USER_CERTS,
  8287. bMultiLines ? wszEMPTY : wszCOMMA,
  8288. pInfo->fOnlyContainsUserCerts ? wszYes : wszNo,
  8289. bMultiLines ? wszCRLF : wszEMPTY))
  8290. {
  8291. goto FormatMessageError;
  8292. }
  8293. //
  8294. // %1!s!Only Contains CA Certs=%2!s!%3!s!
  8295. //
  8296. if (!FormatMessageUnicode(&pwszOnlyContainsCACerts,
  8297. IDS_ONLY_CONTAINS_CA_CERTS,
  8298. bMultiLines ? wszEMPTY : wszCOMMA,
  8299. pInfo->fOnlyContainsCACerts ? wszYes : wszNo,
  8300. bMultiLines ? wszCRLF : wszEMPTY))
  8301. {
  8302. goto FormatMessageError;
  8303. }
  8304. //
  8305. // %1!s!Indirect CRL=%2!s!%3!s!
  8306. //
  8307. if (!FormatMessageUnicode(&pwszIndirectCRL,
  8308. IDS_INDIRECT_CRL,
  8309. bMultiLines ? wszEMPTY : wszCOMMA,
  8310. pInfo->fIndirectCRL ? wszYes : wszNo,
  8311. bMultiLines ? wszCRLF : wszEMPTY))
  8312. {
  8313. goto FormatMessageError;
  8314. }
  8315. //
  8316. // Reallocate and concate to format buffer.
  8317. //
  8318. pwszTemp = (LPWSTR) realloc(pwszFormat, sizeof(WCHAR) *
  8319. (wcslen(pwszFormat) + wcslen(pwszOnlyContainsUserCerts) +
  8320. wcslen(pwszOnlyContainsCACerts) + wcslen(pwszIndirectCRL) + 1));
  8321. if (NULL == pwszTemp)
  8322. {
  8323. goto MemoryError;
  8324. }
  8325. pwszFormat = pwszTemp;
  8326. wcscat(pwszFormat, pwszOnlyContainsUserCerts);
  8327. wcscat(pwszFormat, pwszOnlyContainsCACerts);
  8328. wcscat(pwszFormat, pwszIndirectCRL);
  8329. //
  8330. // Format the CRL reason.
  8331. //
  8332. if (0 != pInfo->OnlySomeReasonFlags.cbData)
  8333. {
  8334. if (!FormatCRLReason(dwCertEncodingType,
  8335. dwFormatType,
  8336. dwFormatStrType,
  8337. pFormatStruct,
  8338. lpszStructType,
  8339. &(pInfo->OnlySomeReasonFlags),
  8340. &pwszCRLReason))
  8341. {
  8342. goto FormatCRLReasonError;
  8343. }
  8344. //
  8345. // Format Decide between single line and mulitple line format.
  8346. //
  8347. if (!FormatMessageUnicode(&pwszReasonFormat,
  8348. bMultiLines ? IDS_CRL_DIST_REASON_MULTI : IDS_CRL_DIST_REASON,
  8349. pwszCRLReason))
  8350. {
  8351. goto FormatMessageError;
  8352. }
  8353. //
  8354. // Reallocate and concate to format buffer.
  8355. //
  8356. pwszTemp = (LPWSTR) realloc(pwszFormat, sizeof(WCHAR) * (wcslen(pwszFormat) + wcslen(pwszReasonFormat) + 1));
  8357. if (NULL == pwszTemp)
  8358. {
  8359. goto MemoryError;
  8360. }
  8361. pwszFormat = pwszTemp;
  8362. wcscat(pwszFormat, pwszReasonFormat);
  8363. LocalFree((HLOCAL) pwszCRLReason);
  8364. pwszCRLReason = NULL;
  8365. LocalFree((HLOCAL) pwszReasonFormat);
  8366. pwszReasonFormat = NULL;
  8367. }
  8368. //
  8369. // length needed.
  8370. //
  8371. cbNeeded = sizeof(WCHAR) * (wcslen(pwszFormat) + 1);
  8372. //
  8373. // length only calculation?
  8374. //
  8375. if (NULL == pbFormat)
  8376. {
  8377. *pcbFormat = cbNeeded;
  8378. goto SuccessReturn;
  8379. }
  8380. //
  8381. // Caller provided us with enough memory?
  8382. //
  8383. if (*pcbFormat < cbNeeded)
  8384. {
  8385. *pcbFormat = cbNeeded;
  8386. goto MoreDataError;
  8387. }
  8388. //
  8389. // Copy size and data.
  8390. //
  8391. memcpy(pbFormat, pwszFormat, cbNeeded);
  8392. *pcbFormat = cbNeeded;
  8393. SuccessReturn:
  8394. fResult = TRUE;
  8395. CommonReturn:
  8396. //
  8397. // Free resources.
  8398. //
  8399. if (pwszCRLReason)
  8400. {
  8401. LocalFree((HLOCAL) pwszCRLReason);
  8402. }
  8403. if (pwszReasonFormat)
  8404. {
  8405. LocalFree((HLOCAL) pwszReasonFormat);
  8406. }
  8407. if(pwszIndirectCRL)
  8408. {
  8409. LocalFree((HLOCAL) pwszIndirectCRL);
  8410. }
  8411. if(pwszOnlyContainsCACerts)
  8412. {
  8413. LocalFree((HLOCAL) pwszOnlyContainsCACerts);
  8414. }
  8415. if(pwszOnlyContainsUserCerts)
  8416. {
  8417. LocalFree((HLOCAL) pwszOnlyContainsUserCerts);
  8418. }
  8419. if(pwszPointName)
  8420. {
  8421. LocalFree((HLOCAL) pwszPointName);
  8422. }
  8423. if (pwszNameFormat)
  8424. {
  8425. LocalFree((HLOCAL) pwszNameFormat);
  8426. }
  8427. if (pwszFormat)
  8428. {
  8429. free(pwszFormat);
  8430. }
  8431. if (pInfo)
  8432. {
  8433. free(pInfo);
  8434. }
  8435. return fResult;
  8436. ErrorReturn:
  8437. fResult=FALSE;
  8438. goto CommonReturn;
  8439. SET_ERROR(InvalidArg,E_INVALIDARG);
  8440. TRACE_ERROR(DecodeGenericError);
  8441. SET_ERROR(MemoryError,E_OUTOFMEMORY);
  8442. TRACE_ERROR(FormatDistPointNameError);
  8443. TRACE_ERROR(LoadStringError);
  8444. TRACE_ERROR(FormatCRLReasonError);
  8445. TRACE_ERROR(FormatMessageError);
  8446. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  8447. }
  8448. //+-----------------------------------------------------------------------------
  8449. //
  8450. // FormatNameConstraintsSubtree.
  8451. //
  8452. // typedef struct _CERT_GENERAL_SUBTREE {
  8453. // CERT_ALT_NAME_ENTRY Base;
  8454. // DWORD dwMinimum;
  8455. // BOOL fMaximum;
  8456. // DWORD dwMaximum;
  8457. // } CERT_GENERAL_SUBTREE, *PCERT_GENERAL_SUBTREE;
  8458. //
  8459. //
  8460. // Note: Intended to be called only by FormatNameConstrants. So no validity
  8461. // checks are done on parameters.
  8462. //
  8463. //------------------------------------------------------------------------------
  8464. //static
  8465. BOOL
  8466. FormatNameConstraintsSubtree (
  8467. DWORD dwCertEncodingType,
  8468. DWORD dwFormatType,
  8469. DWORD dwFormatStrType,
  8470. void *pFormatStruct,
  8471. void *pbFormat,
  8472. DWORD *pcbFormat,
  8473. DWORD idSubtree,
  8474. DWORD cSubtree,
  8475. PCERT_GENERAL_SUBTREE pSubtree)
  8476. {
  8477. BOOL fResult;
  8478. DWORD dwIndex;
  8479. DWORD cbNeeded;
  8480. WCHAR wszOneTab[PRE_FIX_SIZE] = wszEMPTY;
  8481. LPWSTR pwszType = NULL;
  8482. LPWSTR pwszSubtree = NULL;
  8483. LPWSTR pwszAltName = NULL;
  8484. LPWSTR pwszFormat = NULL;
  8485. BOOL bMultiLines = dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE;
  8486. //
  8487. // Any subtree?
  8488. //
  8489. if (0 == cSubtree)
  8490. {
  8491. //
  8492. // Permitted=None%1!s!
  8493. // Excluded=None%1!s!
  8494. //
  8495. if (IDS_NAME_CONSTRAINTS_PERMITTED == idSubtree)
  8496. {
  8497. idSubtree = IDS_NAME_CONSTRAINTS_PERMITTED_NONE;
  8498. }
  8499. else // if (IDS_NAME_CONSTRAINTS_EXCLUDED == idSubtree)
  8500. {
  8501. idSubtree = IDS_NAME_CONSTRAINTS_EXCLUDED_NONE;
  8502. }
  8503. if (!FormatMessageUnicode(&pwszType,
  8504. idSubtree,
  8505. bMultiLines ? wszCRLF : wszEMPTY))
  8506. {
  8507. goto FormatMessageError;
  8508. }
  8509. }
  8510. else
  8511. {
  8512. //
  8513. // "Permitted%1!s!"
  8514. // "Excluded%1!s!"
  8515. //
  8516. if (!FormatMessageUnicode(&pwszType,
  8517. idSubtree,
  8518. bMultiLines ? wszCRLF : wszCOLON))
  8519. {
  8520. goto FormatMessageError;
  8521. }
  8522. //
  8523. // Load tab strings.
  8524. //
  8525. if (!LoadStringU(hFrmtFuncInst,
  8526. IDS_ONE_TAB,
  8527. wszOneTab,
  8528. sizeof(wszOneTab) / sizeof(wszOneTab[0])))
  8529. {
  8530. goto LoadStringError;
  8531. }
  8532. }
  8533. //
  8534. // Allocate format buffer.
  8535. //
  8536. if (!(pwszFormat = (LPWSTR) malloc(sizeof(WCHAR) * (wcslen(pwszType) + 1))))
  8537. {
  8538. goto MemoryError;
  8539. }
  8540. //
  8541. // Initialize formatted string.
  8542. //
  8543. wcscpy(pwszFormat, pwszType);
  8544. //
  8545. // Format each subtree parts.
  8546. //
  8547. for (dwIndex = 0; dwIndex < cSubtree; dwIndex++, pSubtree++)
  8548. {
  8549. LPWSTR pwszTemp;
  8550. //
  8551. // Maximum specified?
  8552. //
  8553. if (pSubtree->fMaximum)
  8554. {
  8555. //
  8556. // "%1!s![%2!d!]Subtrees (%3!d!..%4!d!):%5!s!"
  8557. //
  8558. if (!FormatMessageUnicode(&pwszSubtree,
  8559. IDS_NAME_CONSTRAINTS_SUBTREE,
  8560. bMultiLines ? wszOneTab : dwIndex ? wszCOMMA : wszEMPTY,
  8561. dwIndex + 1,
  8562. pSubtree->dwMinimum,
  8563. pSubtree->dwMaximum,
  8564. bMultiLines ? wszCRLF : wszEMPTY))
  8565. {
  8566. goto FormatMessageError;
  8567. }
  8568. }
  8569. else
  8570. {
  8571. //
  8572. // "%1!s![%2!d!]Subtrees (%3!d!...):%4!s"
  8573. //
  8574. if (!FormatMessageUnicode(&pwszSubtree,
  8575. IDS_NAME_CONSTRAINTS_SUBTREE_NO_MAX,
  8576. bMultiLines ? wszOneTab : dwIndex ? wszCOMMA : wszEMPTY,
  8577. dwIndex + 1,
  8578. pSubtree->dwMinimum,
  8579. bMultiLines ? wszCRLF : wszEMPTY))
  8580. {
  8581. goto FormatMessageError;
  8582. }
  8583. }
  8584. //
  8585. // Reallocate and concate to format buffer.
  8586. //
  8587. pwszTemp = (LPWSTR) realloc(pwszFormat, sizeof(WCHAR) * (wcslen(pwszFormat) + 1 + wcslen(pwszSubtree)));
  8588. if (NULL == pwszTemp)
  8589. {
  8590. goto MemoryError;
  8591. }
  8592. pwszFormat = pwszTemp;
  8593. wcscat(pwszFormat, pwszSubtree);
  8594. LocalFree((HLOCAL) pwszSubtree);
  8595. pwszSubtree = NULL;
  8596. //
  8597. // Format name.
  8598. //
  8599. CERT_ALT_NAME_INFO CertAltNameInfo;
  8600. memset(&CertAltNameInfo, 0, sizeof(CERT_ALT_NAME_INFO));
  8601. CertAltNameInfo.cAltEntry = 1;
  8602. CertAltNameInfo.rgAltEntry = &(pSubtree->Base);
  8603. // Need to tell if it is for multi line format. We need two \t\t
  8604. // in front of each alt name entry
  8605. DWORD ids = bMultiLines ? IDS_TWO_TABS : 0;
  8606. // Get the alternative name entry
  8607. cbNeeded = 0;
  8608. if (!FormatAltNameInfo(dwCertEncodingType,
  8609. dwFormatType,
  8610. dwFormatStrType,
  8611. pFormatStruct,
  8612. ids,
  8613. FALSE,
  8614. &CertAltNameInfo,
  8615. NULL,
  8616. &cbNeeded))
  8617. {
  8618. goto FormatAltNameError;
  8619. }
  8620. if (NULL == (pwszAltName = (LPWSTR) malloc(cbNeeded)))
  8621. {
  8622. goto MemoryError;
  8623. }
  8624. if (!FormatAltNameInfo(dwCertEncodingType,
  8625. dwFormatType,
  8626. dwFormatStrType,
  8627. pFormatStruct,
  8628. ids,
  8629. FALSE,
  8630. &CertAltNameInfo,
  8631. pwszAltName,
  8632. &cbNeeded))
  8633. {
  8634. goto FormatAltNameError;
  8635. }
  8636. //
  8637. // Append "\r\n" if multi-line.
  8638. //
  8639. if (bMultiLines)
  8640. {
  8641. pwszTemp = (LPWSTR) realloc(pwszAltName, sizeof(WCHAR) * (wcslen(pwszAltName) + wcslen(wszCRLF) + 1));
  8642. if (NULL == pwszTemp)
  8643. {
  8644. goto MemoryError;
  8645. }
  8646. pwszAltName = pwszTemp;
  8647. wcscat(pwszAltName, wszCRLF);
  8648. }
  8649. //
  8650. // Reallocate and concate to format buffer.
  8651. //
  8652. pwszTemp = (LPWSTR) realloc(pwszFormat, sizeof(WCHAR) * (wcslen(pwszFormat) + 1 + wcslen(pwszAltName)));
  8653. if (NULL == pwszTemp)
  8654. {
  8655. goto MemoryError;
  8656. }
  8657. pwszFormat = pwszTemp;
  8658. wcscat(pwszFormat, pwszAltName);
  8659. free(pwszAltName);
  8660. pwszAltName = NULL;
  8661. }
  8662. //
  8663. // Total length needed.
  8664. //
  8665. cbNeeded = sizeof(WCHAR) * (wcslen(pwszFormat) + 1);
  8666. //
  8667. // length only calculation?
  8668. //
  8669. if (NULL == pbFormat)
  8670. {
  8671. *pcbFormat = cbNeeded;
  8672. goto SuccessReturn;
  8673. }
  8674. //
  8675. // Caller provided us with enough memory?
  8676. //
  8677. if (*pcbFormat < cbNeeded)
  8678. {
  8679. *pcbFormat = cbNeeded;
  8680. goto MoreDataError;
  8681. }
  8682. //
  8683. // Copy size and data.
  8684. //
  8685. memcpy(pbFormat, pwszFormat, cbNeeded);
  8686. *pcbFormat = cbNeeded;
  8687. SuccessReturn:
  8688. fResult = TRUE;
  8689. CommonReturn:
  8690. //
  8691. // Free resources.
  8692. //
  8693. if (pwszType)
  8694. {
  8695. LocalFree((HLOCAL) pwszType);
  8696. }
  8697. if (pwszSubtree)
  8698. {
  8699. LocalFree((HLOCAL) pwszSubtree);
  8700. }
  8701. if (pwszAltName)
  8702. {
  8703. free((HLOCAL) pwszAltName);
  8704. }
  8705. if (pwszFormat)
  8706. {
  8707. free(pwszFormat);
  8708. }
  8709. return fResult;
  8710. ErrorReturn:
  8711. fResult=FALSE;
  8712. goto CommonReturn;
  8713. TRACE_ERROR(FormatMessageError);
  8714. TRACE_ERROR(LoadStringError);
  8715. SET_ERROR(MemoryError,E_OUTOFMEMORY);
  8716. TRACE_ERROR(FormatAltNameError);
  8717. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  8718. }
  8719. //+-----------------------------------------------------------------------------
  8720. //
  8721. // FormatNameConstrains: szOID_NAME_CONSTRAINTS
  8722. // X509_NAME_CONSTRAINTS
  8723. //
  8724. // typedef struct _CERT_NAME_CONSTRAINTS_INFO {
  8725. // DWORD cPermittedSubtree;
  8726. // PCERT_GENERAL_SUBTREE rgPermittedSubtree;
  8727. // DWORD cExcludedSubtree;
  8728. // PCERT_GENERAL_SUBTREE rgExcludedSubtree;
  8729. // } CERT_NAME_CONSTRAINTS_INFO, *PCERT_NAME_CONSTRAINTS_INFO;
  8730. //
  8731. //------------------------------------------------------------------------------
  8732. //static
  8733. BOOL
  8734. WINAPI
  8735. FormatNameConstraints (
  8736. DWORD dwCertEncodingType,
  8737. DWORD dwFormatType,
  8738. DWORD dwFormatStrType,
  8739. void *pFormatStruct,
  8740. LPCSTR lpszStructType,
  8741. const BYTE *pbEncoded,
  8742. DWORD cbEncoded,
  8743. void *pbFormat,
  8744. DWORD *pcbFormat)
  8745. {
  8746. BOOL fResult = FALSE;
  8747. DWORD cbPermitNeeded = 0;
  8748. DWORD cbExcludeNeeded = 0;
  8749. DWORD cbTotalNeeded = 0;
  8750. PCERT_NAME_CONSTRAINTS_INFO pInfo = NULL;
  8751. //
  8752. // Check input parameters.
  8753. //
  8754. if ((NULL == pbEncoded && 0 != cbEncoded) ||
  8755. (NULL == pcbFormat) || (0 == cbEncoded))
  8756. {
  8757. goto InvalidArg;
  8758. }
  8759. //
  8760. // Decode extension.
  8761. //
  8762. if (!DecodeGenericBLOB(dwCertEncodingType,
  8763. lpszStructType,
  8764. pbEncoded,
  8765. cbEncoded,
  8766. (void **)&pInfo))
  8767. {
  8768. goto DecodeGenericError;
  8769. }
  8770. //
  8771. // Find out memory size needed.
  8772. //
  8773. if ((!FormatNameConstraintsSubtree(dwCertEncodingType,
  8774. dwFormatType,
  8775. dwFormatStrType,
  8776. pFormatStruct,
  8777. NULL,
  8778. &cbPermitNeeded,
  8779. IDS_NAME_CONSTRAINTS_PERMITTED,
  8780. pInfo->cPermittedSubtree,
  8781. pInfo->rgPermittedSubtree)) ||
  8782. (!FormatNameConstraintsSubtree(dwCertEncodingType,
  8783. dwFormatType,
  8784. dwFormatStrType,
  8785. pFormatStruct,
  8786. NULL,
  8787. &cbExcludeNeeded,
  8788. IDS_NAME_CONSTRAINTS_EXCLUDED,
  8789. pInfo->cExcludedSubtree,
  8790. pInfo->rgExcludedSubtree)))
  8791. {
  8792. goto ErrorReturn;
  8793. }
  8794. //
  8795. // Total length needed.
  8796. //
  8797. cbTotalNeeded = cbPermitNeeded + cbExcludeNeeded;
  8798. if (0 == cbTotalNeeded)
  8799. {
  8800. *pcbFormat = cbTotalNeeded;
  8801. goto SuccessReturn;
  8802. }
  8803. //
  8804. // One char less after we concate both strings.
  8805. //
  8806. if (cbPermitNeeded > 0 && cbExcludeNeeded > 0)
  8807. {
  8808. cbTotalNeeded -= sizeof(WCHAR);
  8809. //
  8810. // If not multi-lines and both strings are present, allow 2 more
  8811. // chars for ", " to separate the strings.
  8812. //
  8813. if (!(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
  8814. {
  8815. cbTotalNeeded += sizeof(WCHAR) * wcslen(wszCOMMA);
  8816. }
  8817. }
  8818. //
  8819. // length only calculation?
  8820. //
  8821. if (NULL == pbFormat)
  8822. {
  8823. *pcbFormat = cbTotalNeeded;
  8824. goto SuccessReturn;
  8825. }
  8826. //
  8827. // Caller provided us with enough memory?
  8828. //
  8829. if (*pcbFormat < cbTotalNeeded)
  8830. {
  8831. *pcbFormat = cbTotalNeeded;
  8832. goto MoreDataError;
  8833. }
  8834. //
  8835. // Now format both subtrees.
  8836. //
  8837. if (!FormatNameConstraintsSubtree(dwCertEncodingType,
  8838. dwFormatType,
  8839. dwFormatStrType,
  8840. pFormatStruct,
  8841. pbFormat,
  8842. &cbPermitNeeded,
  8843. IDS_NAME_CONSTRAINTS_PERMITTED,
  8844. pInfo->cPermittedSubtree,
  8845. pInfo->rgPermittedSubtree))
  8846. {
  8847. goto ErrorReturn;
  8848. }
  8849. //
  8850. // If not multi-lines and both strings are present, then add ", "
  8851. // to separate them.
  8852. //
  8853. if (!(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) &&
  8854. (cbPermitNeeded > 0) && (cbExcludeNeeded > 0))
  8855. {
  8856. wcscat((LPWSTR) pbFormat, wszCOMMA);
  8857. }
  8858. pbFormat = (void *) ((BYTE *) pbFormat + wcslen((LPWSTR) pbFormat) * sizeof(WCHAR));
  8859. if (!FormatNameConstraintsSubtree(dwCertEncodingType,
  8860. dwFormatType,
  8861. dwFormatStrType,
  8862. pFormatStruct,
  8863. pbFormat,
  8864. &cbExcludeNeeded,
  8865. IDS_NAME_CONSTRAINTS_EXCLUDED,
  8866. pInfo->cExcludedSubtree,
  8867. pInfo->rgExcludedSubtree))
  8868. {
  8869. goto ErrorReturn;
  8870. }
  8871. //
  8872. // Copy the size needed.
  8873. //
  8874. *pcbFormat = cbTotalNeeded;
  8875. SuccessReturn:
  8876. fResult = TRUE;
  8877. CommonReturn:
  8878. //
  8879. // Free resources.
  8880. //
  8881. if (pInfo)
  8882. {
  8883. free(pInfo);
  8884. }
  8885. return fResult;
  8886. ErrorReturn:
  8887. fResult=FALSE;
  8888. goto CommonReturn;
  8889. SET_ERROR(InvalidArg,E_INVALIDARG);
  8890. TRACE_ERROR(DecodeGenericError);
  8891. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  8892. }
  8893. //+-----------------------------------------------------------------------------
  8894. //
  8895. // FormatCertSrvPreviousCertHash szOID_CERTSRV_PREVIOUS_CERT_HASH
  8896. //
  8897. //------------------------------------------------------------------------------
  8898. static BOOL
  8899. WINAPI
  8900. FormatCertSrvPreviousCertHash (
  8901. DWORD dwCertEncodingType,
  8902. DWORD dwFormatType,
  8903. DWORD dwFormatStrType,
  8904. void *pFormatStruct,
  8905. LPCSTR lpszStructType,
  8906. const BYTE *pbEncoded,
  8907. DWORD cbEncoded,
  8908. void *pbFormat,
  8909. DWORD *pcbFormat)
  8910. {
  8911. BOOL fResult;
  8912. DWORD cbNeeded = 0;
  8913. CRYPT_DATA_BLOB * pInfo = NULL;
  8914. WCHAR * pwszHex = NULL;
  8915. WCHAR * pwszFormat = NULL;
  8916. BOOL bMultiLines = dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE;
  8917. //
  8918. // Check input parameters.
  8919. //
  8920. if ((NULL == pbEncoded && 0 != cbEncoded) ||
  8921. (NULL == pcbFormat) || (0 == cbEncoded))
  8922. {
  8923. goto InvalidArg;
  8924. }
  8925. //
  8926. // Decode extension.
  8927. //
  8928. if (!DecodeGenericBLOB(dwCertEncodingType,
  8929. X509_OCTET_STRING,
  8930. pbEncoded,
  8931. cbEncoded,
  8932. (void **) &pInfo))
  8933. {
  8934. goto DecodeGenericError;
  8935. }
  8936. //
  8937. // Get formatted hex string.
  8938. //
  8939. if(!FormatBytesToHex(0,
  8940. dwFormatType,
  8941. dwFormatStrType,
  8942. pFormatStruct,
  8943. NULL,
  8944. pInfo->pbData,
  8945. pInfo->cbData,
  8946. NULL,
  8947. &cbNeeded))
  8948. {
  8949. goto FormatBytesToHexError;
  8950. }
  8951. if (!(pwszHex = (LPWSTR) malloc(cbNeeded)))
  8952. {
  8953. goto MemoryError;
  8954. }
  8955. if(!FormatBytesToHex(0,
  8956. dwFormatType,
  8957. dwFormatStrType,
  8958. pFormatStruct,
  8959. NULL,
  8960. pInfo->pbData,
  8961. pInfo->cbData,
  8962. pwszHex,
  8963. &cbNeeded))
  8964. {
  8965. goto FormatBytesToHexError;
  8966. }
  8967. if (!FormatMessageUnicode(&pwszFormat,
  8968. IDS_STRING,
  8969. pwszHex,
  8970. bMultiLines ? wszCRLF : wszEMPTY))
  8971. {
  8972. goto FormatMessageError;
  8973. }
  8974. //
  8975. // Total length needed.
  8976. //
  8977. cbNeeded = sizeof(WCHAR) * (wcslen(pwszFormat) + 1);
  8978. //
  8979. // Length only calculation?
  8980. //
  8981. if (NULL == pbFormat)
  8982. {
  8983. *pcbFormat = cbNeeded;
  8984. goto SuccessReturn;
  8985. }
  8986. //
  8987. // Caller provided us with enough memory?
  8988. //
  8989. if (*pcbFormat < cbNeeded)
  8990. {
  8991. *pcbFormat = cbNeeded;
  8992. goto MoreDataError;
  8993. }
  8994. //
  8995. // Copy size and data.
  8996. //
  8997. memcpy(pbFormat, pwszFormat, cbNeeded);
  8998. *pcbFormat = cbNeeded;
  8999. SuccessReturn:
  9000. fResult = TRUE;
  9001. CommonReturn:
  9002. if (pInfo)
  9003. {
  9004. free(pInfo);
  9005. }
  9006. if (pwszHex)
  9007. {
  9008. free(pwszHex);
  9009. }
  9010. if (pwszFormat)
  9011. {
  9012. LocalFree((HLOCAL) pwszFormat);
  9013. }
  9014. return fResult;
  9015. ErrorReturn:
  9016. fResult=FALSE;
  9017. goto CommonReturn;
  9018. SET_ERROR(InvalidArg,E_INVALIDARG);
  9019. TRACE_ERROR(DecodeGenericError);
  9020. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  9021. TRACE_ERROR(FormatBytesToHexError);
  9022. TRACE_ERROR(FormatMessageError);
  9023. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  9024. }
  9025. //+-----------------------------------------------------------------------------
  9026. //
  9027. // FormatPolicyMappings X509_POLICY_MAPPINGS
  9028. // szOID_POLICY_MAPPINGS
  9029. // szOID_APPLICATION_POLICY_MAPPINGS
  9030. //
  9031. //------------------------------------------------------------------------------
  9032. static BOOL
  9033. WINAPI
  9034. FormatPolicyMappings (
  9035. DWORD dwCertEncodingType,
  9036. DWORD dwFormatType,
  9037. DWORD dwFormatStrType,
  9038. void *pFormatStruct,
  9039. LPCSTR lpszStructType,
  9040. const BYTE *pbEncoded,
  9041. DWORD cbEncoded,
  9042. void *pbFormat,
  9043. DWORD *pcbFormat)
  9044. {
  9045. BOOL fResult;
  9046. DWORD dwIndex = 0;
  9047. DWORD cbNeeded = 0;
  9048. char szEmpty[1] = {'\0'};
  9049. LPSTR pszObjectId = NULL;
  9050. LPWSTR pwszFormat = NULL;
  9051. LPWSTR pwszTemp = NULL;
  9052. LPWSTR pwszLine = NULL;
  9053. LPWSTR pwszPolicy = NULL;
  9054. BOOL bMultiLines = dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE;
  9055. CERT_POLICY_MAPPINGS_INFO * pInfo = NULL;
  9056. //
  9057. // Check input parameters.
  9058. //
  9059. if ((NULL == pbEncoded && 0 != cbEncoded) ||
  9060. (NULL == pcbFormat) || (0 == cbEncoded))
  9061. {
  9062. goto InvalidArg;
  9063. }
  9064. //
  9065. // Decode extension.
  9066. //
  9067. if (!DecodeGenericBLOB(dwCertEncodingType,
  9068. X509_POLICY_MAPPINGS,
  9069. pbEncoded,
  9070. cbEncoded,
  9071. (void **) &pInfo))
  9072. {
  9073. goto DecodeGenericError;
  9074. }
  9075. //
  9076. // Make sure data is valid.
  9077. //
  9078. if (pInfo->cPolicyMapping && !pInfo->rgPolicyMapping)
  9079. {
  9080. goto BadDataError;
  9081. }
  9082. //
  9083. // Initialize formatted string.
  9084. //
  9085. if (!(pwszFormat = (LPWSTR) malloc(sizeof(WCHAR))))
  9086. {
  9087. goto MemoryError;
  9088. }
  9089. *pwszFormat = NULL;
  9090. //
  9091. // Loop thru each mapping.
  9092. //
  9093. for (dwIndex = 0; dwIndex < pInfo->cPolicyMapping; dwIndex++)
  9094. {
  9095. //
  9096. // Format Issuer Domain Policy, if available.
  9097. //
  9098. if (pInfo->rgPolicyMapping[dwIndex].pszIssuerDomainPolicy)
  9099. {
  9100. pszObjectId = pInfo->rgPolicyMapping[dwIndex].pszIssuerDomainPolicy;
  9101. }
  9102. else
  9103. {
  9104. pszObjectId = szEmpty;
  9105. }
  9106. if (!FormatObjectId(pszObjectId,
  9107. CRYPT_POLICY_OID_GROUP_ID,
  9108. FALSE,
  9109. &pwszPolicy))
  9110. {
  9111. goto FormatObjectIdError;
  9112. }
  9113. //
  9114. // "[%1!d!]Issuer Domain=%2!s!%3!s!"
  9115. //
  9116. if (!FormatMessageUnicode(&pwszLine,
  9117. IDS_ISSUER_DOMAIN_POLICY,
  9118. dwIndex + 1,
  9119. pwszPolicy,
  9120. bMultiLines ? wszCRLF : wszCOMMA))
  9121. {
  9122. goto FormatMessageError;
  9123. }
  9124. //
  9125. // Reallocate and concate line to format buffer.
  9126. //
  9127. pwszTemp = (LPWSTR) realloc(pwszFormat, sizeof(WCHAR) * (wcslen(pwszFormat) + wcslen(pwszLine) + 1));
  9128. if (NULL == pwszTemp)
  9129. {
  9130. goto MemoryError;
  9131. }
  9132. pwszFormat = pwszTemp;
  9133. wcscat(pwszFormat, pwszLine);
  9134. LocalFree((HLOCAL) pwszPolicy);
  9135. pwszPolicy = NULL;
  9136. LocalFree((HLOCAL) pwszLine);
  9137. pwszLine = NULL;
  9138. //
  9139. // Format Subject Domain Policy, if available.
  9140. //
  9141. if (pInfo->rgPolicyMapping[dwIndex].pszSubjectDomainPolicy)
  9142. {
  9143. pszObjectId = pInfo->rgPolicyMapping[dwIndex].pszSubjectDomainPolicy;
  9144. }
  9145. else
  9146. {
  9147. pszObjectId = szEmpty;
  9148. }
  9149. if (!FormatObjectId(pszObjectId,
  9150. CRYPT_POLICY_OID_GROUP_ID,
  9151. FALSE,
  9152. &pwszPolicy))
  9153. {
  9154. goto FormatObjectIdError;
  9155. }
  9156. //
  9157. // "%1!s!Subject Domain=%2!s!%3!s!"
  9158. //
  9159. if (!FormatMessageUnicode(&pwszLine,
  9160. IDS_SUBJECT_DOMAIN_POLICY,
  9161. bMultiLines ? wszTAB : wszEMPTY,
  9162. pwszPolicy,
  9163. bMultiLines ? wszCRLF : (dwIndex + 1) < pInfo->cPolicyMapping ? wszCOMMA : wszEMPTY))
  9164. {
  9165. goto FormatMessageError;
  9166. }
  9167. //
  9168. // Reallocate and concate line to format buffer.
  9169. //
  9170. pwszTemp = (LPWSTR) realloc(pwszFormat, sizeof(WCHAR) * (wcslen(pwszFormat) + wcslen(pwszLine) + 1));
  9171. if (NULL == pwszTemp)
  9172. {
  9173. goto MemoryError;
  9174. }
  9175. pwszFormat = pwszTemp;
  9176. wcscat(pwszFormat, pwszLine);
  9177. LocalFree((HLOCAL) pwszPolicy);
  9178. pwszPolicy = NULL;
  9179. LocalFree((HLOCAL) pwszLine);
  9180. pwszLine = NULL;
  9181. }
  9182. //
  9183. // Total length needed.
  9184. //
  9185. cbNeeded = sizeof(WCHAR) * (wcslen(pwszFormat) + 1);
  9186. //
  9187. // Length only calculation?
  9188. //
  9189. if (NULL == pbFormat)
  9190. {
  9191. *pcbFormat = cbNeeded;
  9192. goto SuccessReturn;
  9193. }
  9194. //
  9195. // Caller provided us with enough memory?
  9196. //
  9197. if (*pcbFormat < cbNeeded)
  9198. {
  9199. *pcbFormat = cbNeeded;
  9200. goto MoreDataError;
  9201. }
  9202. //
  9203. // Copy size and data.
  9204. //
  9205. memcpy(pbFormat, pwszFormat, cbNeeded);
  9206. *pcbFormat = cbNeeded;
  9207. SuccessReturn:
  9208. fResult = TRUE;
  9209. CommonReturn:
  9210. if (pwszLine)
  9211. {
  9212. LocalFree((HLOCAL) pwszLine);
  9213. }
  9214. if (pwszPolicy)
  9215. {
  9216. LocalFree((HLOCAL) pwszPolicy);
  9217. }
  9218. if (pwszFormat)
  9219. {
  9220. free(pwszFormat);
  9221. }
  9222. if (pInfo)
  9223. {
  9224. free(pInfo);
  9225. }
  9226. return fResult;
  9227. ErrorReturn:
  9228. fResult=FALSE;
  9229. goto CommonReturn;
  9230. SET_ERROR(InvalidArg,E_INVALIDARG);
  9231. TRACE_ERROR(DecodeGenericError);
  9232. SET_ERROR(BadDataError, E_POINTER);
  9233. TRACE_ERROR(FormatObjectIdError);
  9234. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  9235. TRACE_ERROR(FormatMessageError);
  9236. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  9237. }
  9238. //+-----------------------------------------------------------------------------
  9239. //
  9240. // FormatPolicyConstraints X509_POLICY_CONSTRAINTS
  9241. // szOID_POLICY_CONSTRAINTS
  9242. // szOID_APPLICATION_POLICY_CONSTRAINTS
  9243. //
  9244. //------------------------------------------------------------------------------
  9245. static BOOL
  9246. WINAPI
  9247. FormatPolicyConstraints (
  9248. DWORD dwCertEncodingType,
  9249. DWORD dwFormatType,
  9250. DWORD dwFormatStrType,
  9251. void *pFormatStruct,
  9252. LPCSTR lpszStructType,
  9253. const BYTE *pbEncoded,
  9254. DWORD cbEncoded,
  9255. void *pbFormat,
  9256. DWORD *pcbFormat)
  9257. {
  9258. BOOL fResult;
  9259. DWORD cbNeeded = 0;
  9260. LPWSTR pwszFormat = NULL;
  9261. LPWSTR pwszTemp = NULL;
  9262. LPWSTR pwszLine = NULL;
  9263. BOOL bMultiLines = dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE;
  9264. CERT_POLICY_CONSTRAINTS_INFO * pInfo = NULL;
  9265. //
  9266. // Check input parameters.
  9267. //
  9268. if ((NULL == pbEncoded && 0 != cbEncoded) ||
  9269. (NULL == pcbFormat) || (0 == cbEncoded))
  9270. {
  9271. goto InvalidArg;
  9272. }
  9273. //
  9274. // Decode extension.
  9275. //
  9276. if (!DecodeGenericBLOB(dwCertEncodingType,
  9277. X509_POLICY_CONSTRAINTS,
  9278. pbEncoded,
  9279. cbEncoded,
  9280. (void **) &pInfo))
  9281. {
  9282. goto DecodeGenericError;
  9283. }
  9284. //
  9285. // Initialize formatted string.
  9286. //
  9287. if (!(pwszFormat = (LPWSTR) malloc(sizeof(WCHAR))))
  9288. {
  9289. goto MemoryError;
  9290. }
  9291. *pwszFormat = NULL;
  9292. //
  9293. // Format Required Explicit Policy Skip Certs, if available.
  9294. //
  9295. if (pInfo->fRequireExplicitPolicy)
  9296. {
  9297. //
  9298. // "Required Explicit Policy Skip Certs=%1!d!%2!s!"
  9299. //
  9300. if (!FormatMessageUnicode(&pwszLine,
  9301. IDS_REQUIRED_EXPLICIT_POLICY_SKIP_CERTS,
  9302. pInfo->dwRequireExplicitPolicySkipCerts,
  9303. bMultiLines ? wszCRLF : wszCOMMA))
  9304. {
  9305. goto FormatMessageError;
  9306. }
  9307. //
  9308. // Reallocate and concate line to format buffer.
  9309. //
  9310. pwszTemp = (LPWSTR) realloc(pwszFormat, sizeof(WCHAR) * (wcslen(pwszFormat) + wcslen(pwszLine) + 1));
  9311. if (NULL == pwszTemp)
  9312. {
  9313. goto MemoryError;
  9314. }
  9315. pwszFormat = pwszTemp;
  9316. wcscat(pwszFormat, pwszLine);
  9317. LocalFree((HLOCAL) pwszLine);
  9318. pwszLine = NULL;
  9319. }
  9320. //
  9321. // Format Inhibit Policy Mapping Skip Certs, if available.
  9322. //
  9323. if (pInfo->fInhibitPolicyMapping)
  9324. {
  9325. //
  9326. // "Inhibit Policy Mapping Skip Certs=%1!d!%2!s!"
  9327. //
  9328. if (!FormatMessageUnicode(&pwszLine,
  9329. IDS_INHIBIT_POLICY_MAPPING_SKIP_CERTS,
  9330. pInfo->dwInhibitPolicyMappingSkipCerts,
  9331. bMultiLines ? wszCRLF : wszEMPTY))
  9332. {
  9333. goto FormatMessageError;
  9334. }
  9335. //
  9336. // Reallocate and concate line to format buffer.
  9337. //
  9338. pwszTemp = (LPWSTR) realloc(pwszFormat, sizeof(WCHAR) * (wcslen(pwszFormat) + wcslen(pwszLine) + 1));
  9339. if (NULL == pwszTemp)
  9340. {
  9341. goto MemoryError;
  9342. }
  9343. pwszFormat = pwszTemp;
  9344. wcscat(pwszFormat, pwszLine);
  9345. LocalFree((HLOCAL) pwszLine);
  9346. pwszLine = NULL;
  9347. }
  9348. //
  9349. // Total length needed.
  9350. //
  9351. cbNeeded = sizeof(WCHAR) * (wcslen(pwszFormat) + 1);
  9352. //
  9353. // Length only calculation?
  9354. //
  9355. if (NULL == pbFormat)
  9356. {
  9357. *pcbFormat = cbNeeded;
  9358. goto SuccessReturn;
  9359. }
  9360. //
  9361. // Caller provided us with enough memory?
  9362. //
  9363. if (*pcbFormat < cbNeeded)
  9364. {
  9365. *pcbFormat = cbNeeded;
  9366. goto MoreDataError;
  9367. }
  9368. //
  9369. // Copy size and data.
  9370. //
  9371. memcpy(pbFormat, pwszFormat, cbNeeded);
  9372. *pcbFormat = cbNeeded;
  9373. SuccessReturn:
  9374. fResult = TRUE;
  9375. CommonReturn:
  9376. if (pwszLine)
  9377. {
  9378. LocalFree((HLOCAL) pwszLine);
  9379. }
  9380. if (pwszFormat)
  9381. {
  9382. free(pwszFormat);
  9383. }
  9384. if (pInfo)
  9385. {
  9386. free(pInfo);
  9387. }
  9388. return fResult;
  9389. ErrorReturn:
  9390. fResult=FALSE;
  9391. goto CommonReturn;
  9392. SET_ERROR(InvalidArg,E_INVALIDARG);
  9393. TRACE_ERROR(DecodeGenericError);
  9394. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  9395. TRACE_ERROR(FormatMessageError);
  9396. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  9397. }
  9398. //+-----------------------------------------------------------------------------
  9399. //
  9400. // FormatCertificateTemplate X509_CERTIFICATE_TEMPLATE
  9401. // szOID_CERTIFICATE_TEMPLATE
  9402. //
  9403. //------------------------------------------------------------------------------
  9404. static BOOL
  9405. WINAPI
  9406. FormatCertificateTemplate (
  9407. DWORD dwCertEncodingType,
  9408. DWORD dwFormatType,
  9409. DWORD dwFormatStrType,
  9410. void *pFormatStruct,
  9411. LPCSTR lpszStructType,
  9412. const BYTE *pbEncoded,
  9413. DWORD cbEncoded,
  9414. void *pbFormat,
  9415. DWORD *pcbFormat)
  9416. {
  9417. BOOL fResult;
  9418. DWORD cbNeeded = 0;
  9419. LPWSTR pwszFormat = NULL;
  9420. LPWSTR pwszObjId = NULL;
  9421. LPWSTR pwszTemp = NULL;
  9422. LPWSTR pwszLine = NULL;
  9423. BOOL bMultiLines = dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE;
  9424. CERT_TEMPLATE_EXT * pInfo = NULL;
  9425. //
  9426. // Check input parameters.
  9427. //
  9428. if ((NULL == pbEncoded && 0 != cbEncoded) ||
  9429. (NULL == pcbFormat) || (0 == cbEncoded))
  9430. {
  9431. goto InvalidArg;
  9432. }
  9433. //
  9434. // Decode extension.
  9435. //
  9436. if (!DecodeGenericBLOB(dwCertEncodingType,
  9437. X509_CERTIFICATE_TEMPLATE,
  9438. pbEncoded,
  9439. cbEncoded,
  9440. (void **) &pInfo))
  9441. {
  9442. goto DecodeGenericError;
  9443. }
  9444. //
  9445. // Initialize formatted string.
  9446. //
  9447. if (!(pwszFormat = (LPWSTR) malloc(sizeof(WCHAR))))
  9448. {
  9449. goto MemoryError;
  9450. }
  9451. *pwszFormat = NULL;
  9452. #if (0) //DSIE: Bug 157853
  9453. //
  9454. // Convert OID to Unicode.
  9455. //
  9456. if (!AllocateAnsiToUnicode(pInfo->pszObjId, &pwszObjId))
  9457. {
  9458. goto AnsiToUnicodeError;
  9459. }
  9460. #else
  9461. if (!FormatObjectId(pInfo->pszObjId,
  9462. CRYPT_TEMPLATE_OID_GROUP_ID,
  9463. FALSE,
  9464. &pwszObjId))
  9465. {
  9466. goto FormatObjectIdError;
  9467. }
  9468. #endif
  9469. //
  9470. // "Template=%1!s!%2!s!Major Version Number=%3!d!%4!s!"
  9471. //
  9472. if (!FormatMessageUnicode(&pwszLine,
  9473. IDS_CERTIFICATE_TEMPLATE_MAJOR_VERSION,
  9474. pwszObjId,
  9475. bMultiLines ? wszCRLF : wszCOMMA,
  9476. pInfo->dwMajorVersion,
  9477. bMultiLines ? wszCRLF : wszCOMMA))
  9478. {
  9479. goto FormatMessageError;
  9480. }
  9481. //
  9482. // Reallocate and concate line to format buffer.
  9483. //
  9484. pwszTemp = (LPWSTR) realloc(pwszFormat, sizeof(WCHAR) * (wcslen(pwszFormat) + wcslen(pwszLine) + 1));
  9485. if (NULL == pwszTemp)
  9486. {
  9487. goto MemoryError;
  9488. }
  9489. pwszFormat = pwszTemp;
  9490. wcscat(pwszFormat, pwszLine);
  9491. LocalFree((HLOCAL) pwszLine);
  9492. pwszLine = NULL;
  9493. //
  9494. // Format Minor Version, if available.
  9495. //
  9496. if (pInfo->fMinorVersion)
  9497. {
  9498. //
  9499. // "Minor Version Number=%1!d!%2!s!"
  9500. //
  9501. if (!FormatMessageUnicode(&pwszLine,
  9502. IDS_CERTIFICATE_TEMPLATE_MINOR_VERSION,
  9503. pInfo->dwMinorVersion,
  9504. bMultiLines ? wszCRLF : wszEMPTY))
  9505. {
  9506. goto FormatMessageError;
  9507. }
  9508. //
  9509. // Reallocate and concate line to format buffer.
  9510. //
  9511. pwszTemp = (LPWSTR) realloc(pwszFormat, sizeof(WCHAR) * (wcslen(pwszFormat) + wcslen(pwszLine) + 1));
  9512. if (NULL == pwszTemp)
  9513. {
  9514. goto MemoryError;
  9515. }
  9516. pwszFormat = pwszTemp;
  9517. wcscat(pwszFormat, pwszLine);
  9518. LocalFree((HLOCAL) pwszLine);
  9519. pwszLine = NULL;
  9520. }
  9521. //
  9522. // Total length needed.
  9523. //
  9524. cbNeeded = sizeof(WCHAR) * (wcslen(pwszFormat) + 1);
  9525. //
  9526. // Length only calculation?
  9527. //
  9528. if (NULL == pbFormat)
  9529. {
  9530. *pcbFormat = cbNeeded;
  9531. goto SuccessReturn;
  9532. }
  9533. //
  9534. // Caller provided us with enough memory?
  9535. //
  9536. if (*pcbFormat < cbNeeded)
  9537. {
  9538. *pcbFormat = cbNeeded;
  9539. goto MoreDataError;
  9540. }
  9541. //
  9542. // Copy size and data.
  9543. //
  9544. memcpy(pbFormat, pwszFormat, cbNeeded);
  9545. *pcbFormat = cbNeeded;
  9546. SuccessReturn:
  9547. fResult = TRUE;
  9548. CommonReturn:
  9549. if (pwszObjId)
  9550. {
  9551. #if (0) //DSIE: Bug 157853
  9552. free(pwszObjId);
  9553. #else
  9554. LocalFree((HLOCAL) pwszObjId);
  9555. #endif
  9556. }
  9557. if (pwszLine)
  9558. {
  9559. LocalFree((HLOCAL) pwszLine);
  9560. }
  9561. if (pwszFormat)
  9562. {
  9563. free(pwszFormat);
  9564. }
  9565. if (pInfo)
  9566. {
  9567. free(pInfo);
  9568. }
  9569. return fResult;
  9570. ErrorReturn:
  9571. fResult=FALSE;
  9572. goto CommonReturn;
  9573. SET_ERROR(InvalidArg,E_INVALIDARG);
  9574. TRACE_ERROR(DecodeGenericError);
  9575. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  9576. #if (0) //DSIE: Bug 157853
  9577. TRACE_ERROR(AnsiToUnicodeError);
  9578. #else
  9579. TRACE_ERROR(FormatObjectIdError);
  9580. #endif
  9581. TRACE_ERROR(FormatMessageError);
  9582. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  9583. }
  9584. //--------------------------------------------------------------------------
  9585. //
  9586. // FormatXCertDistPoints: X509_CROSS_CERT_DIST_POINTS
  9587. // szOID_CROSS_CERT_DIST_POINTS
  9588. //--------------------------------------------------------------------------
  9589. static BOOL
  9590. WINAPI
  9591. FormatXCertDistPoints(
  9592. DWORD dwCertEncodingType,
  9593. DWORD dwFormatType,
  9594. DWORD dwFormatStrType,
  9595. void *pFormatStruct,
  9596. LPCSTR lpszStructType,
  9597. const BYTE *pbEncoded,
  9598. DWORD cbEncoded,
  9599. void *pbFormat,
  9600. DWORD *pcbFormat)
  9601. {
  9602. LPWSTR pwszFormat=NULL;
  9603. LPWSTR pwszDeltaTime=NULL;
  9604. LPWSTR pwszEntryLine=NULL;
  9605. LPWSTR pwszDistPoint=NULL;
  9606. PCROSS_CERT_DIST_POINTS_INFO pInfo=NULL;
  9607. DWORD cbNeeded=0;
  9608. DWORD dwIndex=0;
  9609. BOOL fResult=FALSE;
  9610. BOOL bMultiLines = dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE;
  9611. LPWSTR pwszTemp;
  9612. //check for input parameters
  9613. if ((NULL==pbEncoded && cbEncoded!=0) || (NULL==pcbFormat))
  9614. goto InvalidArg;
  9615. if (cbEncoded==0)
  9616. {
  9617. *pcbFormat=0;
  9618. goto InvalidArg;
  9619. }
  9620. if (!DecodeGenericBLOB(dwCertEncodingType, lpszStructType,
  9621. pbEncoded, cbEncoded, (void **)&pInfo))
  9622. goto DecodeGenericError;
  9623. //
  9624. // "Delta Sync Time=%1!d! seconds%2!s!"
  9625. //
  9626. if (!FormatMessageUnicode(&pwszDeltaTime,
  9627. IDS_XCERT_DELTA_SYNC_TIME,
  9628. pInfo->dwSyncDeltaTime,
  9629. bMultiLines ? wszCRLF : wszCOMMA))
  9630. {
  9631. goto FormatMessageError;
  9632. }
  9633. pwszFormat=(LPWSTR)malloc(sizeof(WCHAR) * (wcslen(pwszDeltaTime)+1));
  9634. if(NULL==pwszFormat)
  9635. goto MemoryError;
  9636. wcscpy(pwszFormat, pwszDeltaTime);
  9637. //format the xcert dist point entries.
  9638. for (dwIndex=0; dwIndex<pInfo->cDistPoint; dwIndex++)
  9639. {
  9640. cbNeeded=0;
  9641. if (!FormatAltNameInfo(dwCertEncodingType,
  9642. dwFormatType,
  9643. dwFormatStrType,
  9644. pFormatStruct,
  9645. bMultiLines ? IDS_ONE_TAB : 0,
  9646. FALSE,
  9647. &pInfo->rgDistPoint[dwIndex],
  9648. NULL,
  9649. &cbNeeded))
  9650. goto FormatAltNameError;
  9651. pwszEntryLine=(LPWSTR)malloc(cbNeeded);
  9652. if (NULL==pwszEntryLine)
  9653. goto MemoryError;
  9654. if (!FormatAltNameInfo(dwCertEncodingType,
  9655. dwFormatType,
  9656. dwFormatStrType,
  9657. pFormatStruct,
  9658. bMultiLines ? IDS_ONE_TAB : 0,
  9659. FALSE,
  9660. &pInfo->rgDistPoint[dwIndex],
  9661. pwszEntryLine,
  9662. &cbNeeded))
  9663. goto FormatAltNameError;
  9664. //"[%1!d!]Cross-Certificate Distribution Point: %2!s!%3!s!%4!s!"
  9665. if(!FormatMessageUnicode(&pwszDistPoint,
  9666. IDS_XCERT_DIST_POINT,
  9667. dwIndex + 1,
  9668. bMultiLines ? wszCRLF : wszEMPTY,
  9669. pwszEntryLine,
  9670. bMultiLines || (dwIndex == pInfo->cDistPoint - 1) ? wszCRLF : wszCOMMA))
  9671. goto FormatMessageError;
  9672. pwszTemp=(LPWSTR)realloc(pwszFormat, sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(pwszDistPoint)+1));
  9673. if(NULL==pwszTemp)
  9674. goto MemoryError;
  9675. pwszFormat = pwszTemp;
  9676. wcscat(pwszFormat, pwszDistPoint);
  9677. //free memory
  9678. free(pwszEntryLine);
  9679. pwszEntryLine=NULL;
  9680. LocalFree((HLOCAL) pwszDistPoint);
  9681. pwszDistPoint=NULL;
  9682. }
  9683. if(0==wcslen(pwszFormat))
  9684. {
  9685. //no data
  9686. pwszFormat=(LPWSTR)malloc(sizeof(WCHAR)*(NO_INFO_SIZE+1));
  9687. if(NULL==pwszFormat)
  9688. goto MemoryError;
  9689. if(!LoadStringU(hFrmtFuncInst,IDS_NO_INFO, pwszFormat, NO_INFO_SIZE))
  9690. goto LoadStringError;
  9691. }
  9692. cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
  9693. //length only calculation
  9694. if(NULL==pbFormat)
  9695. {
  9696. *pcbFormat=cbNeeded;
  9697. fResult=TRUE;
  9698. goto CommonReturn;
  9699. }
  9700. if((*pcbFormat)<cbNeeded)
  9701. {
  9702. *pcbFormat=cbNeeded;
  9703. goto MoreDataError;
  9704. }
  9705. //copy the data
  9706. memcpy(pbFormat, pwszFormat, cbNeeded);
  9707. //copy the size
  9708. *pcbFormat=cbNeeded;
  9709. fResult=TRUE;
  9710. CommonReturn:
  9711. if(pwszDeltaTime)
  9712. LocalFree((HLOCAL) pwszDeltaTime);
  9713. if(pwszDistPoint)
  9714. LocalFree((HLOCAL) pwszDistPoint);
  9715. if(pwszEntryLine)
  9716. free(pwszEntryLine);
  9717. if (pwszFormat)
  9718. free(pwszFormat);
  9719. if(pInfo)
  9720. free(pInfo);
  9721. return fResult;
  9722. ErrorReturn:
  9723. fResult=FALSE;
  9724. goto CommonReturn;
  9725. SET_ERROR(InvalidArg, E_INVALIDARG);
  9726. TRACE_ERROR(DecodeGenericError);
  9727. SET_ERROR(MoreDataError,ERROR_MORE_DATA);
  9728. TRACE_ERROR(LoadStringError);
  9729. TRACE_ERROR(FormatMessageError);
  9730. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  9731. TRACE_ERROR(FormatAltNameError);
  9732. }