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.

910 lines
25 KiB

  1. //+-------------------------------------------------------------------------
  2. // Microsoft Windows
  3. //
  4. // Copyright (C) Microsoft Corporation, 1995 - 1996
  5. //
  6. // File: ossutil.cpp
  7. //
  8. // Contents: OSS ASN.1 compiler utility helper functions.
  9. //
  10. // Functions: OssUtilReverseBytes
  11. // OssUtilAllocAndReverseBytes
  12. // OssUtilGetOctetString
  13. // OssUtilSetHugeInteger
  14. // OssUtilFreeHugeInteger
  15. // OssUtilGetHugeInteger
  16. // OssUtilSetHugeUINT
  17. // OssUtilGetHugeUINT
  18. // OssUtilSetBitString
  19. // OssUtilGetBitString
  20. // OssUtilGetIA5String
  21. // OssUtilSetUnicodeConvertedToIA5String
  22. // OssUtilFreeUnicodeConvertedToIA5String
  23. // OssUtilGetIA5StringConvertedToUnicode
  24. // OssUtilGetBMPString
  25. // OssUtilSetAny
  26. // OssUtilGetAny
  27. // OssUtilEncodeInfoEx
  28. // OssUtilEncodeInfo
  29. // OssUtilDecodeAndAllocInfo
  30. // OssUtilFreeInfo
  31. // OssUtilAllocStructInfoEx
  32. // OssUtilDecodeAndAllocInfoEx
  33. //
  34. // The Get functions decrement *plRemainExtra and advance
  35. // *ppbExtra. When *plRemainExtra becomes negative, the functions continue
  36. // with the length calculation but stop doing any copies.
  37. // The functions don't return an error for a negative *plRemainExtra.
  38. //
  39. // History: 17-Nov-96 philh created
  40. //--------------------------------------------------------------------------
  41. #include "global.hxx"
  42. #include <dbgdef.h>
  43. #include "badstrfunctions.h"
  44. // All the *pvInfo extra stuff needs to be aligned
  45. #define INFO_LEN_ALIGN(Len) ((Len + 7) & ~7)
  46. #if 0 // JLS
  47. //+-------------------------------------------------------------------------
  48. // Reverses a buffer of bytes in place
  49. //--------------------------------------------------------------------------
  50. void
  51. WINAPI
  52. OssUtilReverseBytes(
  53. IN OUT PBYTE pbIn,
  54. IN DWORD cbIn
  55. )
  56. {
  57. // reverse in place
  58. PBYTE pbLo;
  59. PBYTE pbHi;
  60. BYTE bTmp;
  61. for (pbLo = pbIn, pbHi = pbIn + cbIn - 1; pbLo < pbHi; pbHi--, pbLo++) {
  62. bTmp = *pbHi;
  63. *pbHi = *pbLo;
  64. *pbLo = bTmp;
  65. }
  66. }
  67. //+-------------------------------------------------------------------------
  68. // Reverses a buffer of bytes to a new buffer. OssUtilFree() must be
  69. // called to free allocated bytes.
  70. //--------------------------------------------------------------------------
  71. PBYTE
  72. WINAPI
  73. OssUtilAllocAndReverseBytes(
  74. IN PBYTE pbIn,
  75. IN DWORD cbIn
  76. )
  77. {
  78. PBYTE pbOut;
  79. PBYTE pbSrc;
  80. PBYTE pbDst;
  81. DWORD cb;
  82. if (NULL == (pbOut = (PBYTE)OssUtilAlloc(cbIn)))
  83. return NULL;
  84. for (pbSrc = pbIn, pbDst = pbOut + cbIn - 1, cb = cbIn; cb > 0; cb--)
  85. *pbDst-- = *pbSrc++;
  86. return pbOut;
  87. }
  88. #endif // 0 // JLS
  89. //+-------------------------------------------------------------------------
  90. // Get Octet String
  91. //--------------------------------------------------------------------------
  92. void
  93. WINAPI
  94. OssUtilGetOctetString(
  95. IN unsigned int OssLength,
  96. IN unsigned char *OssValue,
  97. IN DWORD dwFlags,
  98. OUT PCRYPT_DATA_BLOB pInfo,
  99. IN OUT BYTE **ppbExtra,
  100. IN OUT LONG *plRemainExtra
  101. )
  102. {
  103. if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG) {
  104. if (*plRemainExtra >= 0) {
  105. pInfo->cbData = OssLength;
  106. pInfo->pbData = OssValue;
  107. }
  108. } else {
  109. LONG lRemainExtra = *plRemainExtra;
  110. BYTE *pbExtra = *ppbExtra;
  111. LONG lAlignExtra;
  112. LONG lData;
  113. lData = (LONG) OssLength;
  114. lAlignExtra = INFO_LEN_ALIGN(lData);
  115. lRemainExtra -= lAlignExtra;
  116. if (lRemainExtra >= 0) {
  117. if (lData > 0) {
  118. pInfo->pbData = pbExtra;
  119. pInfo->cbData = (DWORD) lData;
  120. memcpy(pbExtra, OssValue, lData);
  121. } else
  122. memset(pInfo, 0, sizeof(*pInfo));
  123. pbExtra += lAlignExtra;
  124. }
  125. *plRemainExtra = lRemainExtra;
  126. *ppbExtra = pbExtra;
  127. }
  128. }
  129. #if 0 // JLS
  130. //+-------------------------------------------------------------------------
  131. // Set/Free/Get HugeInteger
  132. //
  133. // BUGBUG: BYTE reversal::
  134. // - this only needs to be done for little endian
  135. // - this needs to be fixed in the OSS compiler
  136. //
  137. // For OssUtilSetInteger, OssUtilFreeInteger must be called to free
  138. // the allocated OssValue.
  139. //--------------------------------------------------------------------------
  140. BOOL
  141. WINAPI
  142. OssUtilSetHugeInteger(
  143. IN PCRYPT_INTEGER_BLOB pInfo,
  144. OUT unsigned int *pOssLength,
  145. OUT unsigned char **ppOssValue
  146. )
  147. {
  148. if (pInfo->cbData > 0) {
  149. if (NULL == (*ppOssValue = OssUtilAllocAndReverseBytes(
  150. pInfo->pbData, pInfo->cbData))) {
  151. *pOssLength = 0;
  152. return FALSE;
  153. }
  154. } else
  155. *ppOssValue = NULL;
  156. *pOssLength = pInfo->cbData;
  157. return TRUE;
  158. }
  159. void
  160. WINAPI
  161. OssUtilFreeHugeInteger(
  162. IN unsigned char *pOssValue
  163. )
  164. {
  165. // Only for BYTE reversal
  166. OssUtilFree(pOssValue);
  167. }
  168. void
  169. WINAPI
  170. OssUtilGetHugeInteger(
  171. IN unsigned int OssLength,
  172. IN unsigned char *pOssValue,
  173. IN DWORD dwFlags,
  174. OUT PCRYPT_INTEGER_BLOB pInfo,
  175. IN OUT BYTE **ppbExtra,
  176. IN OUT LONG *plRemainExtra
  177. )
  178. {
  179. // Since bytes need to be reversed, always need to do a copy (dwFlags = 0)
  180. OssUtilGetOctetString(OssLength, pOssValue, 0,
  181. pInfo, ppbExtra, plRemainExtra);
  182. if (*plRemainExtra >= 0 && pInfo->cbData > 0)
  183. OssUtilReverseBytes(pInfo->pbData, pInfo->cbData);
  184. }
  185. //+-------------------------------------------------------------------------
  186. // Set/Free/Get Huge Unsigned Integer
  187. //
  188. // Set inserts a leading 0x00 before reversing. Note, any extra leading
  189. // 0x00's are removed by OSS before ASN.1 encoding.
  190. //
  191. // Get removes a leading 0x00 if present, after reversing.
  192. //
  193. // OssUtilFreeHugeUINT must be called to free the allocated OssValue.
  194. // OssUtilFreeHugeUINT has been #define'd to OssUtilFreeHugeInteger.
  195. //--------------------------------------------------------------------------
  196. BOOL
  197. WINAPI
  198. OssUtilSetHugeUINT(
  199. IN PCRYPT_UINT_BLOB pInfo,
  200. OUT unsigned int *pOssLength,
  201. OUT unsigned char **ppOssValue
  202. )
  203. {
  204. BOOL fResult;
  205. DWORD cb = pInfo->cbData;
  206. BYTE *pb;
  207. DWORD i;
  208. if (cb > 0) {
  209. if (NULL == (pb = (BYTE *) OssUtilAlloc(cb + 1)))
  210. goto ErrorReturn;
  211. *pb = 0x00;
  212. for (i = 0; i < cb; i++)
  213. pb[1 + i] = pInfo->pbData[cb - 1 - i];
  214. cb++;
  215. } else
  216. pb = NULL;
  217. fResult = TRUE;
  218. CommonReturn:
  219. *pOssLength = cb;
  220. *ppOssValue = pb;
  221. return fResult;
  222. ErrorReturn:
  223. cb = 0;
  224. fResult = FALSE;
  225. goto CommonReturn;
  226. }
  227. void
  228. WINAPI
  229. OssUtilGetHugeUINT(
  230. IN unsigned int OssLength,
  231. IN unsigned char *pOssValue,
  232. IN DWORD dwFlags,
  233. OUT PCRYPT_UINT_BLOB pInfo,
  234. IN OUT BYTE **ppbExtra,
  235. IN OUT LONG *plRemainExtra
  236. )
  237. {
  238. // Check for and advance past a leading 0x00.
  239. if (OssLength > 1 && *pOssValue == 0) {
  240. pOssValue++;
  241. OssLength--;
  242. }
  243. OssUtilGetHugeInteger(
  244. OssLength,
  245. pOssValue,
  246. dwFlags,
  247. pInfo,
  248. ppbExtra,
  249. plRemainExtra
  250. );
  251. }
  252. //+-------------------------------------------------------------------------
  253. // Set/Get BitString
  254. //--------------------------------------------------------------------------
  255. void
  256. WINAPI
  257. OssUtilSetBitString(
  258. IN PCRYPT_BIT_BLOB pInfo,
  259. OUT unsigned int *pOssBitLength,
  260. OUT unsigned char **ppOssValue
  261. )
  262. {
  263. if (pInfo->cbData) {
  264. *ppOssValue = pInfo->pbData;
  265. assert(pInfo->cUnusedBits <= 7);
  266. *pOssBitLength = pInfo->cbData * 8 - pInfo->cUnusedBits;
  267. } else {
  268. *ppOssValue = NULL;
  269. *pOssBitLength = 0;
  270. }
  271. }
  272. static const BYTE rgbUnusedAndMask[8] =
  273. {0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80};
  274. void
  275. WINAPI
  276. OssUtilGetBitString(
  277. IN unsigned int OssBitLength,
  278. IN unsigned char *pOssValue,
  279. IN DWORD dwFlags,
  280. OUT PCRYPT_BIT_BLOB pInfo,
  281. IN OUT BYTE **ppbExtra,
  282. IN OUT LONG *plRemainExtra
  283. )
  284. {
  285. if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG && 0 == (OssBitLength % 8)) {
  286. if (*plRemainExtra >= 0) {
  287. pInfo->cbData = OssBitLength / 8;
  288. pInfo->cUnusedBits = 0;
  289. pInfo->pbData = pOssValue;
  290. }
  291. } else {
  292. LONG lRemainExtra = *plRemainExtra;
  293. BYTE *pbExtra = *ppbExtra;
  294. LONG lAlignExtra;
  295. LONG lData;
  296. DWORD cUnusedBits;
  297. lData = (LONG) OssBitLength / 8;
  298. cUnusedBits = OssBitLength % 8;
  299. if (cUnusedBits) {
  300. cUnusedBits = 8 - cUnusedBits;
  301. lData++;
  302. }
  303. lAlignExtra = INFO_LEN_ALIGN(lData);
  304. lRemainExtra -= lAlignExtra;
  305. if (lRemainExtra >= 0) {
  306. if (lData > 0) {
  307. pInfo->pbData = pbExtra;
  308. pInfo->cbData = (DWORD) lData;
  309. pInfo->cUnusedBits = cUnusedBits;
  310. memcpy(pbExtra, pOssValue, lData);
  311. if (cUnusedBits)
  312. *(pbExtra + lData - 1) &= rgbUnusedAndMask[cUnusedBits];
  313. } else
  314. memset(pInfo, 0, sizeof(*pInfo));
  315. pbExtra += lAlignExtra;
  316. }
  317. *plRemainExtra = lRemainExtra;
  318. *ppbExtra = pbExtra;
  319. }
  320. }
  321. //+-------------------------------------------------------------------------
  322. // Get IA5 String
  323. //--------------------------------------------------------------------------
  324. void
  325. WINAPI
  326. OssUtilGetIA5String(
  327. IN unsigned int OssLength,
  328. IN char *pOssValue,
  329. IN DWORD dwFlags,
  330. OUT LPSTR *ppsz,
  331. IN OUT BYTE **ppbExtra,
  332. IN OUT LONG *plRemainExtra
  333. )
  334. {
  335. LONG lRemainExtra = *plRemainExtra;
  336. BYTE *pbExtra = *ppbExtra;
  337. LONG lAlignExtra;
  338. LONG lData;
  339. lData = (LONG) OssLength;
  340. lAlignExtra = INFO_LEN_ALIGN(lData + 1);
  341. lRemainExtra -= lAlignExtra;
  342. if (lRemainExtra >= 0) {
  343. if (lData > 0)
  344. memcpy(pbExtra, pOssValue, lData);
  345. *(pbExtra + lData) = 0;
  346. *ppsz = (LPSTR) pbExtra;
  347. pbExtra += lAlignExtra;
  348. }
  349. *plRemainExtra = lRemainExtra;
  350. *ppbExtra = pbExtra;
  351. }
  352. //+-------------------------------------------------------------------------
  353. // Set/Free/Get Unicode mapped to IA5 String
  354. //--------------------------------------------------------------------------
  355. BOOL
  356. WINAPI
  357. OssUtilSetUnicodeConvertedToIA5String(
  358. IN LPWSTR pwsz,
  359. OUT unsigned int *pOssLength,
  360. OUT char **ppOssValue
  361. )
  362. {
  363. BOOL fResult;
  364. LPSTR psz = NULL;
  365. int cchUTF8;
  366. int cchWideChar;
  367. int i;
  368. cchWideChar = wcslen(pwsz);
  369. if (cchWideChar == 0) {
  370. *pOssLength = 0;
  371. *ppOssValue = 0;
  372. return TRUE;
  373. }
  374. // Check that the input string contains valid IA5 characters
  375. for (i = 0; i < cchWideChar; i++) {
  376. if (pwsz[i] > 0x7F) {
  377. SetLastError((DWORD) CRYPT_E_INVALID_IA5_STRING);
  378. *pOssLength = (unsigned int) i;
  379. goto InvalidIA5;
  380. }
  381. }
  382. cchUTF8 = WideCharToUTF8(
  383. pwsz,
  384. cchWideChar,
  385. NULL, // lpUTF8Str
  386. 0 // cchUTF8
  387. );
  388. if (cchUTF8 <= 0)
  389. goto ErrorReturn;
  390. if (NULL == (psz = (LPSTR) OssUtilAlloc(cchUTF8)))
  391. goto ErrorReturn;
  392. cchUTF8 = WideCharToUTF8(
  393. pwsz,
  394. cchWideChar,
  395. psz,
  396. cchUTF8
  397. );
  398. *ppOssValue = psz;
  399. *pOssLength = cchUTF8;
  400. fResult = TRUE;
  401. goto CommonReturn;
  402. ErrorReturn:
  403. *pOssLength = 0;
  404. InvalidIA5:
  405. *ppOssValue = NULL;
  406. fResult = FALSE;
  407. CommonReturn:
  408. return fResult;
  409. }
  410. void
  411. WINAPI
  412. OssUtilFreeUnicodeConvertedToIA5String(
  413. IN char *pOssValue
  414. )
  415. {
  416. OssUtilFree(pOssValue);
  417. }
  418. void
  419. WINAPI
  420. OssUtilGetIA5StringConvertedToUnicode(
  421. IN unsigned int OssLength,
  422. IN char *pOssValue,
  423. IN DWORD dwFlags,
  424. OUT LPWSTR *ppwsz,
  425. IN OUT BYTE **ppbExtra,
  426. IN OUT LONG *plRemainExtra
  427. )
  428. {
  429. LONG lRemainExtra = *plRemainExtra;
  430. BYTE *pbExtra = *ppbExtra;
  431. LONG lAlignExtra;
  432. LONG lData;
  433. int cchWideChar;
  434. cchWideChar = UTF8ToWideChar(
  435. (LPSTR) pOssValue,
  436. OssLength,
  437. NULL, // lpWideCharStr
  438. 0 // cchWideChar
  439. );
  440. if (cchWideChar > 0)
  441. lData = cchWideChar * sizeof(WCHAR);
  442. else
  443. lData = 0;
  444. lAlignExtra = INFO_LEN_ALIGN(lData + sizeof(WCHAR));
  445. lRemainExtra -= lAlignExtra;
  446. if (lRemainExtra >= 0) {
  447. if (lData > 0)
  448. UTF8ToWideChar(pOssValue, OssLength,
  449. (LPWSTR) pbExtra, cchWideChar);
  450. memset(pbExtra + lData, 0, sizeof(WCHAR));
  451. *ppwsz = (LPWSTR) pbExtra;
  452. pbExtra += lAlignExtra;
  453. }
  454. *plRemainExtra = lRemainExtra;
  455. *ppbExtra = pbExtra;
  456. }
  457. //+-------------------------------------------------------------------------
  458. // Get BMP String
  459. //--------------------------------------------------------------------------
  460. void
  461. WINAPI
  462. OssUtilGetBMPString(
  463. IN unsigned int OssLength,
  464. IN unsigned short *pOssValue,
  465. IN DWORD dwFlags,
  466. OUT LPWSTR *ppwsz,
  467. IN OUT BYTE **ppbExtra,
  468. IN OUT LONG *plRemainExtra
  469. )
  470. {
  471. LONG lRemainExtra = *plRemainExtra;
  472. BYTE *pbExtra = *ppbExtra;
  473. LONG lAlignExtra;
  474. LONG lData;
  475. lData = (LONG) OssLength * sizeof(WCHAR);
  476. lAlignExtra = INFO_LEN_ALIGN(lData + sizeof(WCHAR));
  477. lRemainExtra -= lAlignExtra;
  478. if (lRemainExtra >= 0) {
  479. if (lData > 0)
  480. memcpy(pbExtra, pOssValue, lData);
  481. memset(pbExtra + lData, 0, sizeof(WCHAR));
  482. *ppwsz = (LPWSTR) pbExtra;
  483. pbExtra += lAlignExtra;
  484. }
  485. *plRemainExtra = lRemainExtra;
  486. *ppbExtra = pbExtra;
  487. }
  488. #endif // 0 // JLS
  489. //+-------------------------------------------------------------------------
  490. // Set/Get "Any" DER BLOB
  491. //--------------------------------------------------------------------------
  492. void
  493. WINAPI
  494. OssUtilSetAny(
  495. IN PCRYPT_OBJID_BLOB pInfo,
  496. OUT OpenType *pOss
  497. )
  498. {
  499. memset(pOss, 0, sizeof(*pOss));
  500. pOss->encoded = pInfo->pbData;
  501. pOss->length = pInfo->cbData;
  502. }
  503. void
  504. WINAPI
  505. OssUtilGetAny(
  506. IN OpenType *pOss,
  507. IN DWORD dwFlags,
  508. OUT PCRYPT_OBJID_BLOB pInfo,
  509. IN OUT BYTE **ppbExtra,
  510. IN OUT LONG *plRemainExtra
  511. )
  512. {
  513. if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG) {
  514. if (*plRemainExtra >= 0) {
  515. pInfo->cbData = pOss->length;
  516. pInfo->pbData = (BYTE *) pOss->encoded;
  517. }
  518. } else {
  519. LONG lRemainExtra = *plRemainExtra;
  520. BYTE *pbExtra = *ppbExtra;
  521. LONG lAlignExtra;
  522. LONG lData;
  523. lData = (LONG) pOss->length;
  524. lAlignExtra = INFO_LEN_ALIGN(lData);
  525. lRemainExtra -= lAlignExtra;
  526. if (lRemainExtra >= 0) {
  527. if (lData > 0) {
  528. pInfo->pbData = pbExtra;
  529. pInfo->cbData = (DWORD) lData;
  530. memcpy(pbExtra, pOss->encoded, lData);
  531. } else
  532. memset(pInfo, 0, sizeof(*pInfo));
  533. pbExtra += lAlignExtra;
  534. }
  535. *plRemainExtra = lRemainExtra;
  536. *ppbExtra = pbExtra;
  537. }
  538. }
  539. //+-------------------------------------------------------------------------
  540. // Encode an OSS formatted info structure.
  541. //
  542. // If CRYPT_ENCODE_ALLOC_FLAG is set, allocate memory for pbEncoded and
  543. // return *((BYTE **) pvEncoded) = pbAllocEncoded. Otherwise,
  544. // pvEncoded points to byte array to be updated.
  545. //--------------------------------------------------------------------------
  546. BOOL
  547. WINAPI
  548. OssUtilEncodeInfoEx(
  549. IN OssGlobal *Pog,
  550. IN int pdunum,
  551. IN void *pvOssInfo,
  552. IN DWORD dwFlags,
  553. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  554. OUT OPTIONAL void *pvEncoded,
  555. IN OUT DWORD *pcbEncoded
  556. )
  557. {
  558. BOOL fResult;
  559. DWORD cbEncoded;
  560. OssBuf OssEncoded;
  561. int OssStatus;
  562. unsigned char *value;
  563. if (NULL == pvEncoded || (dwFlags & CRYPT_ENCODE_ALLOC_FLAG))
  564. cbEncoded = 0;
  565. else
  566. cbEncoded = *pcbEncoded;
  567. OssEncoded.length = cbEncoded;
  568. if (cbEncoded == 0)
  569. value = NULL;
  570. else
  571. value = (unsigned char *) pvEncoded;
  572. OssEncoded.value = value;
  573. ossSetEncodingRules(Pog, OSS_DER);
  574. OssStatus = ossEncode(
  575. Pog,
  576. pdunum,
  577. pvOssInfo,
  578. &OssEncoded);
  579. cbEncoded = OssEncoded.length;
  580. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG) {
  581. PFN_CRYPT_ALLOC pfnAlloc;
  582. BYTE *pbEncoded;
  583. if (0 != OssStatus || 0 == cbEncoded) {
  584. ossFreeBuf(Pog, OssEncoded.value);
  585. *((void **) pvEncoded) = NULL;
  586. goto OssError;
  587. }
  588. pfnAlloc = PkiGetEncodeAllocFunction(pEncodePara);
  589. if (NULL == (pbEncoded = (BYTE *) pfnAlloc(cbEncoded))) {
  590. ossFreeBuf(Pog, OssEncoded.value);
  591. *((void **) pvEncoded) = NULL;
  592. goto OutOfMemory;
  593. }
  594. memcpy(pbEncoded, OssEncoded.value, cbEncoded);
  595. *((BYTE **) pvEncoded) = pbEncoded;
  596. ossFreeBuf(Pog, OssEncoded.value);
  597. goto SuccessReturn;
  598. } else if (value == NULL && OssEncoded.value) {
  599. // Length only calculation with a throw away allocation
  600. ossFreeBuf(Pog, OssEncoded.value);
  601. if (pvEncoded && 0 == OssStatus) {
  602. // Upon entry *pcbEncoded == 0
  603. goto LengthError;
  604. }
  605. }
  606. if (0 != OssStatus) {
  607. // For MORE_BUF:: redo as a length only calculation
  608. if (OssStatus == MORE_BUF && pvEncoded &&
  609. OssUtilEncodeInfoEx(
  610. Pog,
  611. pdunum,
  612. pvOssInfo,
  613. 0, // dwFlags
  614. NULL, // pEncodePara
  615. NULL, // pbEncoded
  616. &cbEncoded))
  617. goto LengthError;
  618. else {
  619. cbEncoded = 0;
  620. goto OssError;
  621. }
  622. }
  623. SuccessReturn:
  624. fResult = TRUE;
  625. CommonReturn:
  626. *pcbEncoded = cbEncoded;
  627. return fResult;
  628. ErrorReturn:
  629. fResult = FALSE;
  630. goto CommonReturn;
  631. TRACE_ERROR(OutOfMemory)
  632. SET_ERROR(LengthError, ERROR_MORE_DATA)
  633. SET_ERROR_VAR(OssError, CRYPT_E_OSS_ERROR + OssStatus)
  634. }
  635. #if 0 // JLS
  636. //+-------------------------------------------------------------------------
  637. // Encode an OSS formatted info structure
  638. //--------------------------------------------------------------------------
  639. BOOL
  640. WINAPI
  641. OssUtilEncodeInfo(
  642. IN OssGlobal *Pog,
  643. IN int pdunum,
  644. IN void *pvOssInfo,
  645. OUT OPTIONAL BYTE *pbEncoded,
  646. IN OUT DWORD *pcbEncoded
  647. )
  648. {
  649. return OssUtilEncodeInfoEx(
  650. Pog,
  651. pdunum,
  652. pvOssInfo,
  653. 0, // dwFlags
  654. NULL, // pEncodePara
  655. pbEncoded,
  656. pcbEncoded
  657. );
  658. }
  659. #endif // 0 // JLS
  660. //+-------------------------------------------------------------------------
  661. // Decode into an allocated, OSS formatted info structure
  662. //--------------------------------------------------------------------------
  663. BOOL
  664. WINAPI
  665. OssUtilDecodeAndAllocInfo(
  666. IN OssGlobal *Pog,
  667. IN int pdunum,
  668. IN const BYTE *pbEncoded,
  669. IN DWORD cbEncoded,
  670. OUT void **ppvOssInfo
  671. )
  672. {
  673. BOOL fResult;
  674. OssBuf OssEncoded;
  675. int OssStatus;
  676. OssEncoded.length = cbEncoded;
  677. OssEncoded.value = (unsigned char *) pbEncoded;
  678. ossSetEncodingRules(Pog, OSS_BER);
  679. *ppvOssInfo = NULL;
  680. if (0 != (OssStatus = ossDecode(
  681. Pog,
  682. &pdunum,
  683. &OssEncoded,
  684. ppvOssInfo)))
  685. goto OssError;
  686. fResult = TRUE;
  687. CommonReturn:
  688. return fResult;
  689. ErrorReturn:
  690. *ppvOssInfo = NULL;
  691. fResult = FALSE;
  692. goto CommonReturn;
  693. SET_ERROR_VAR(OssError, CRYPT_E_OSS_ERROR + OssStatus)
  694. }
  695. //+-------------------------------------------------------------------------
  696. // Free an allocated, OSS formatted info structure
  697. //--------------------------------------------------------------------------
  698. void
  699. WINAPI
  700. OssUtilFreeInfo(
  701. IN OssGlobal *Pog,
  702. IN int pdunum,
  703. IN void *pvOssInfo
  704. )
  705. {
  706. if (pvOssInfo) {
  707. ossFreePDU(Pog, pdunum, pvOssInfo);
  708. }
  709. }
  710. //+-------------------------------------------------------------------------
  711. // Call the callback to convert the OSS structure into the 'C' structure.
  712. // If CRYPT_DECODE_ALLOC_FLAG is set allocate memory for the 'C'
  713. // structure and call the callback initially to get the length and then
  714. // a second time to update the allocated 'C' structure.
  715. //
  716. // Allocated structure is returned:
  717. // *((void **) pvStructInfo) = pvAllocStructInfo
  718. //--------------------------------------------------------------------------
  719. BOOL
  720. WINAPI
  721. OssUtilAllocStructInfoEx(
  722. IN void *pvOssInfo,
  723. IN DWORD dwFlags,
  724. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  725. IN PFN_OSS_UTIL_DECODE_EX_CALLBACK pfnDecodeExCallback,
  726. OUT OPTIONAL void *pvStructInfo,
  727. IN OUT DWORD *pcbStructInfo
  728. )
  729. {
  730. BOOL fResult;
  731. LONG lRemainExtra;
  732. DWORD cbStructInfo;
  733. if (NULL == pvStructInfo || (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) {
  734. cbStructInfo = 0;
  735. lRemainExtra = 0;
  736. } else {
  737. cbStructInfo = *pcbStructInfo;
  738. lRemainExtra = (LONG) cbStructInfo;
  739. }
  740. if (!pfnDecodeExCallback(
  741. pvOssInfo,
  742. dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
  743. pDecodePara,
  744. pvStructInfo,
  745. &lRemainExtra
  746. )) goto DecodeCallbackError;
  747. if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) {
  748. void *pv;
  749. PFN_CRYPT_ALLOC pfnAlloc = PkiGetDecodeAllocFunction(pDecodePara);
  750. assert(0 > lRemainExtra);
  751. lRemainExtra = -lRemainExtra;
  752. cbStructInfo = (DWORD) lRemainExtra;
  753. if (NULL == (pv = pfnAlloc(cbStructInfo)))
  754. goto OutOfMemory;
  755. if (!pfnDecodeExCallback(
  756. pvOssInfo,
  757. dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
  758. pDecodePara,
  759. pv,
  760. &lRemainExtra
  761. )) {
  762. PFN_CRYPT_FREE pfnFree = PkiGetDecodeFreeFunction(pDecodePara);
  763. pfnFree(pv);
  764. goto DecodeCallbackError;
  765. }
  766. *((void **) pvStructInfo) = pv;
  767. assert(0 <= lRemainExtra);
  768. }
  769. if (0 <= lRemainExtra) {
  770. cbStructInfo = cbStructInfo - (DWORD) lRemainExtra;
  771. } else {
  772. cbStructInfo = cbStructInfo + (DWORD) -lRemainExtra;
  773. if (pvStructInfo) {
  774. SetLastError((DWORD) ERROR_MORE_DATA);
  775. fResult = FALSE;
  776. goto CommonReturn;
  777. }
  778. }
  779. fResult = TRUE;
  780. CommonReturn:
  781. *pcbStructInfo = cbStructInfo;
  782. return fResult;
  783. ErrorReturn:
  784. if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
  785. *((void **) pvStructInfo) = NULL;
  786. cbStructInfo = 0;
  787. fResult = FALSE;
  788. goto CommonReturn;
  789. TRACE_ERROR(DecodeCallbackError)
  790. TRACE_ERROR(OutOfMemory)
  791. }
  792. //+-------------------------------------------------------------------------
  793. // Decode the OSS formatted info structure and call the callback
  794. // function to convert the OSS structure to the 'C' structure.
  795. //
  796. // If CRYPT_DECODE_ALLOC_FLAG is set allocate memory for the 'C'
  797. // structure and call the callback initially to get the length and then
  798. // a second time to update the allocated 'C' structure.
  799. //
  800. // Allocated structure is returned:
  801. // *((void **) pvStructInfo) = pvAllocStructInfo
  802. //--------------------------------------------------------------------------
  803. BOOL
  804. WINAPI
  805. OssUtilDecodeAndAllocInfoEx(
  806. IN OssGlobal *Pog,
  807. IN int pdunum,
  808. IN const BYTE *pbEncoded,
  809. IN DWORD cbEncoded,
  810. IN DWORD dwFlags,
  811. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  812. IN PFN_OSS_UTIL_DECODE_EX_CALLBACK pfnDecodeExCallback,
  813. OUT OPTIONAL void *pvStructInfo,
  814. IN OUT DWORD *pcbStructInfo
  815. )
  816. {
  817. BOOL fResult;
  818. void *pvOssInfo = NULL;
  819. if (!OssUtilDecodeAndAllocInfo(
  820. Pog,
  821. pdunum,
  822. pbEncoded,
  823. cbEncoded,
  824. &pvOssInfo
  825. )) goto OssDecodeError;
  826. fResult = OssUtilAllocStructInfoEx(
  827. pvOssInfo,
  828. dwFlags,
  829. pDecodePara,
  830. pfnDecodeExCallback,
  831. pvStructInfo,
  832. pcbStructInfo
  833. );
  834. CommonReturn:
  835. OssUtilFreeInfo(Pog, pdunum, pvOssInfo);
  836. return fResult;
  837. ErrorReturn:
  838. if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
  839. *((void **) pvStructInfo) = NULL;
  840. *pcbStructInfo = 0;
  841. fResult = FALSE;
  842. goto CommonReturn;
  843. TRACE_ERROR(OssDecodeError)
  844. }