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.

976 lines
30 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996 - 1999
  6. //
  7. // File: jvimage.cpp
  8. //
  9. // Contents: Microsoft SIP Provider (JAVA utilities)
  10. //
  11. // History: 15-Feb-1997 pberkman created
  12. //
  13. //--------------------------------------------------------------------------
  14. #include "global.hxx"
  15. BOOL SeekAndReadFile(HANDLE hFile, DWORD lFileOffset,BYTE *pb,
  16. DWORD cb);
  17. BOOL SeekAndWriteFile(HANDLE hFile, DWORD lFileOffset, BYTE *pb,
  18. DWORD cb);
  19. typedef void *HSHPDIGESTDATA;
  20. typedef BOOL (WINAPI *PFN_SHP_DIGEST_DATA)(HSHPDIGESTDATA hDigestData,
  21. BYTE *pbData,
  22. DWORD cbData);
  23. typedef void *HSHPSIGNFILE;
  24. typedef struct _JAVA_OPEN_ARG
  25. {
  26. HANDLE hFile;
  27. } JAVA_OPEN_ARG, *PJAVA_OPEN_ARG;
  28. typedef struct _JAVA_FUNC_PARA
  29. {
  30. HANDLE hFile;
  31. BYTE *pbSignedData;
  32. } JAVA_FUNC_PARA, *PJAVA_FUNC_PARA;
  33. typedef struct _JAVA_DIGEST_PARA
  34. {
  35. BOOL fDisableDigest;
  36. PFN_SHP_DIGEST_DATA pfnDigestData;
  37. HSHPDIGESTDATA hDigestData;
  38. } JAVA_DIGEST_PARA, *PJAVA_DIGEST_PARA;
  39. typedef struct _JAVA_SIGN_PARA
  40. {
  41. WORD wConstPoolCount;
  42. WORD wSignConstPoolIndex;
  43. LONG lSignConstPoolOffset;
  44. WORD wAttrCount;
  45. LONG lAttrCountOffset;
  46. WORD wSignAttrIndex;
  47. DWORD dwSignAttrLength;
  48. LONG lSignAttrOffset;
  49. LONG lEndOfFileOffset;
  50. } JAVA_SIGN_PARA, *PJAVA_SIGN_PARA;
  51. typedef struct _JAVA_READ_PARA
  52. {
  53. BOOL fResult;
  54. DWORD dwLastError;
  55. LONG lFileOffset;
  56. DWORD cbCacheRead;
  57. DWORD cbCacheRemain;
  58. } JAVA_READ_PARA, *PJAVA_READ_PARA;
  59. #define JAVA_READ_CACHE_LEN 512
  60. typedef struct _JAVA_PARA
  61. {
  62. JAVA_FUNC_PARA Func;
  63. JAVA_DIGEST_PARA Digest;
  64. JAVA_SIGN_PARA Sign;
  65. JAVA_READ_PARA Read;
  66. BYTE rgbCache[JAVA_READ_CACHE_LEN];
  67. } JAVA_PARA, *PJAVA_PARA;
  68. #define JAVA_MAGIC 0xCAFEBABE
  69. #define JAVA_MINOR_VERSION 3
  70. #define JAVA_MAJOR_VERSION 45
  71. // Constant Pool tags
  72. //
  73. // Note: CONSTANT_Long and CONSTANT_Double use two constant pool indexes.
  74. enum
  75. {
  76. CONSTANT_Utf8 = 1,
  77. CONSTANT_Unicode = 2,
  78. CONSTANT_Integer = 3,
  79. CONSTANT_Float = 4,
  80. CONSTANT_Long = 5,
  81. CONSTANT_Double = 6,
  82. CONSTANT_Class = 7,
  83. CONSTANT_String = 8,
  84. CONSTANT_Fieldref = 9,
  85. CONSTANT_Methodref = 10,
  86. CONSTANT_InterfaceMethodref = 11,
  87. CONSTANT_NameAndType = 12
  88. };
  89. // Constant Pool Info lengths (excludes the tag)
  90. DWORD rgConstPoolLength[] =
  91. {
  92. 0, // tag of zero not used
  93. 0, // CONSTANT_Utf8 (special case)
  94. 0, // CONSTANT_Unicode (special case)
  95. 4, // CONSTANT_Integer_info
  96. 4, // CONSTANT_Float_info
  97. 8, // CONSTANT_Long_info
  98. 8, // CONSTANT_Double_info
  99. 2, // CONSTANT_Class_info
  100. 2, // CONSTANT_String_info
  101. 4, // CONSTANT_Fieldref_info
  102. 4, // CONSTANT_Methodref_info
  103. 4, // CONSTANT_InterfaceMethodref_info
  104. 4 // CONSTANT_NameAndType_info
  105. };
  106. static inline void *ShpAlloc(DWORD cbytes)
  107. {
  108. void *pvRet;
  109. pvRet = (void *)new BYTE[cbytes];
  110. if (!(pvRet))
  111. {
  112. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  113. }
  114. return(pvRet);
  115. }
  116. static inline void ShpFree(void *pv)
  117. {
  118. if (pv)
  119. {
  120. delete pv;
  121. }
  122. }
  123. // The following functions convert to/from Java bytes which are big endian
  124. static inline void ToJavaU2(WORD w, BYTE rgb[])
  125. {
  126. rgb[0] = HIBYTE(w);
  127. rgb[1] = LOBYTE(w);
  128. }
  129. static inline WORD FromJavaU2(BYTE rgb[])
  130. {
  131. return ((WORD)rgb[0]<<8) | ((WORD)rgb[1]<<0);
  132. }
  133. static inline void ToJavaU4(DWORD dw, BYTE rgb[])
  134. {
  135. rgb[0] = HIBYTE(HIWORD(dw));
  136. rgb[1] = LOBYTE(HIWORD(dw));
  137. rgb[2] = HIBYTE(LOWORD(dw));
  138. rgb[3] = LOBYTE(LOWORD(dw));
  139. }
  140. static inline DWORD FromJavaU4(BYTE rgb[])
  141. {
  142. return ((DWORD)rgb[0]<<24) |
  143. ((DWORD)rgb[1]<<16) |
  144. ((DWORD)rgb[2]<<8) |
  145. ((DWORD)rgb[3]<<0);
  146. }
  147. #define CONST_POOL_COUNT_OFFSET 8
  148. #define UTF8_HDR_LENGTH (1+2)
  149. #define ATTR_HDR_LENGTH (2+4)
  150. #define SIGN_ATTR_NAME_LENGTH 19
  151. #define SIGN_CONST_POOL_LENGTH (UTF8_HDR_LENGTH + SIGN_ATTR_NAME_LENGTH)
  152. static const char rgchSignAttrName[SIGN_ATTR_NAME_LENGTH + 1] =
  153. "_digital_signature_";
  154. //+-------------------------------------------------------------------------
  155. // Shift the bytes in the file.
  156. //
  157. // If lbShift is positive, the bytes are shifted toward the end of the file.
  158. // If lbShift is negative, the bytes are shifted toward the start of the file.
  159. //--------------------------------------------------------------------------
  160. static
  161. BOOL
  162. JavaShiftFileBytes(
  163. IN HANDLE hFile,
  164. IN PBYTE pbCache,
  165. IN LONG cbCache,
  166. IN LONG lStartOffset,
  167. IN LONG lEndOffset,
  168. IN LONG lbShift
  169. )
  170. {
  171. LONG cbTotalMove, cbMove;
  172. cbTotalMove = lEndOffset - lStartOffset;
  173. while (cbTotalMove) {
  174. cbMove = min(cbTotalMove, cbCache);
  175. if (lbShift > 0) {
  176. if (!SeekAndReadFile(hFile, lEndOffset - cbMove,
  177. pbCache, cbMove))
  178. return FALSE;
  179. if (!SeekAndWriteFile(hFile, (lEndOffset - cbMove) + lbShift,
  180. pbCache, cbMove))
  181. return FALSE;
  182. lEndOffset -= cbMove;
  183. } else if (lbShift < 0) {
  184. if (!SeekAndReadFile(hFile, lStartOffset, pbCache, cbMove))
  185. return FALSE;
  186. if (!SeekAndWriteFile(hFile, lStartOffset + lbShift,
  187. pbCache, cbMove))
  188. return FALSE;
  189. lStartOffset += cbMove;
  190. }
  191. cbTotalMove -= cbMove;
  192. }
  193. return TRUE;
  194. }
  195. //+-------------------------------------------------------------------------
  196. // Low level functions for reading the Java Class File.
  197. //
  198. // If not disabled, the read bytes are also hashed.
  199. //
  200. // For an error, remaining unread values are zero'ed and
  201. // pPara->Read.fResult = FALSE.
  202. //--------------------------------------------------------------------------
  203. static void ReadJavaBytes(
  204. IN PJAVA_PARA pPara,
  205. OUT OPTIONAL BYTE *pb, // if NULL, bytes are hashed and then skipped
  206. IN DWORD cb
  207. )
  208. {
  209. DWORD cbCacheRemain = pPara->Read.cbCacheRemain;
  210. DWORD lFileOffset = pPara->Read.lFileOffset;
  211. BOOL fDisableDigest = pPara->Digest.pfnDigestData == NULL ||
  212. pPara->Digest.fDisableDigest;
  213. if (!pPara->Read.fResult)
  214. goto ErrorReturn;
  215. while (cb > 0) {
  216. DWORD cbCopy;
  217. BYTE *pbCache;
  218. if (cbCacheRemain == 0) {
  219. if (!ReadFile(pPara->Func.hFile, pPara->rgbCache,
  220. sizeof(pPara->rgbCache), &cbCacheRemain, NULL))
  221. goto ErrorReturn;
  222. if (cbCacheRemain == 0) goto ErrorReturn;
  223. pPara->Read.cbCacheRead = cbCacheRemain;
  224. }
  225. cbCopy = min(cb, cbCacheRemain);
  226. pbCache = &pPara->rgbCache[pPara->Read.cbCacheRead - cbCacheRemain];
  227. if (!fDisableDigest) {
  228. if (!pPara->Digest.pfnDigestData(
  229. pPara->Digest.hDigestData,
  230. pbCache,
  231. cbCopy)) goto ErrorReturn;
  232. }
  233. if (pb) {
  234. memcpy(pb, pbCache, cbCopy);
  235. pb += cbCopy;
  236. }
  237. cb -= cbCopy;
  238. cbCacheRemain -= cbCopy;
  239. lFileOffset += cbCopy;
  240. }
  241. goto CommonReturn;
  242. ErrorReturn:
  243. if (pPara->Read.fResult) {
  244. // First error
  245. pPara->Read.fResult = FALSE;
  246. pPara->Read.dwLastError = GetLastError();
  247. }
  248. if (pb && cb)
  249. memset(pb, 0, cb);
  250. CommonReturn:
  251. pPara->Read.cbCacheRemain = cbCacheRemain;
  252. pPara->Read.lFileOffset = lFileOffset;
  253. }
  254. static void SkipJavaBytes(IN PJAVA_PARA pPara, IN DWORD cb)
  255. {
  256. ReadJavaBytes(pPara, NULL, cb);
  257. }
  258. static BYTE ReadJavaU1(IN PJAVA_PARA pPara)
  259. {
  260. BYTE b;
  261. ReadJavaBytes(pPara, &b, 1);
  262. return b;
  263. }
  264. static WORD ReadJavaU2(IN PJAVA_PARA pPara)
  265. {
  266. BYTE rgb[2];
  267. ReadJavaBytes(pPara, rgb, 2);
  268. return FromJavaU2(rgb);
  269. }
  270. static DWORD ReadJavaU4(IN PJAVA_PARA pPara)
  271. {
  272. BYTE rgb[4];
  273. ReadJavaBytes(pPara, rgb, 4);
  274. return FromJavaU4(rgb);
  275. }
  276. //+-------------------------------------------------------------------------
  277. // .
  278. //--------------------------------------------------------------------------
  279. static
  280. BOOL
  281. GetSignedDataFromJavaClassFile(
  282. IN HSHPSIGNFILE hSignFile,
  283. OUT BYTE **ppbSignedData,
  284. OUT DWORD *pcbSignedData
  285. )
  286. {
  287. BOOL fResult;
  288. PJAVA_PARA pPara = (PJAVA_PARA) hSignFile;
  289. BYTE *pbSignedData = NULL;
  290. DWORD cbSignedData;
  291. cbSignedData = pPara->Sign.dwSignAttrLength;
  292. if (cbSignedData == 0) {
  293. SetLastError((DWORD)TRUST_E_NOSIGNATURE);
  294. goto ErrorReturn;
  295. }
  296. pbSignedData = pPara->Func.pbSignedData;
  297. if (pbSignedData == NULL) {
  298. if (NULL == (pbSignedData = (BYTE *) ShpAlloc(cbSignedData)))
  299. goto ErrorReturn;
  300. if (!SeekAndReadFile(
  301. pPara->Func.hFile,
  302. pPara->Sign.lSignAttrOffset + ATTR_HDR_LENGTH,
  303. pbSignedData,
  304. cbSignedData))
  305. goto ErrorReturn;
  306. pPara->Func.pbSignedData = pbSignedData;
  307. }
  308. fResult = TRUE;
  309. goto CommonReturn;
  310. ErrorReturn:
  311. if (pbSignedData) {
  312. ShpFree(pbSignedData);
  313. pbSignedData = NULL;
  314. }
  315. cbSignedData = 0;
  316. fResult = FALSE;
  317. CommonReturn:
  318. *ppbSignedData = pbSignedData;
  319. *pcbSignedData = cbSignedData;
  320. return fResult;
  321. }
  322. //+-------------------------------------------------------------------------
  323. // .
  324. //--------------------------------------------------------------------------
  325. static
  326. BOOL
  327. SetSignedDataIntoJavaClassFile(
  328. IN HSHPSIGNFILE hSignFile,
  329. IN const BYTE *pbSignedData,
  330. IN DWORD cbSignedData
  331. )
  332. {
  333. PJAVA_PARA pPara = (PJAVA_PARA) hSignFile;
  334. HANDLE hFile = pPara->Func.hFile;
  335. if (pbSignedData == NULL || cbSignedData == 0)
  336. // Length only
  337. return TRUE;
  338. if (pPara->Sign.wSignConstPoolIndex == pPara->Sign.wConstPoolCount) {
  339. BYTE rgb[SIGN_CONST_POOL_LENGTH];
  340. // Add a new constant pool entry for the name of the
  341. // signed data attribute.
  342. // First, make room in the file by shifting all the bytes that follow.
  343. if (!JavaShiftFileBytes(
  344. pPara->Func.hFile,
  345. pPara->rgbCache,
  346. sizeof(pPara->rgbCache),
  347. pPara->Sign.lSignConstPoolOffset,
  348. pPara->Sign.lEndOfFileOffset,
  349. SIGN_CONST_POOL_LENGTH))
  350. return FALSE;
  351. // Update offsets that have been shifted
  352. pPara->Sign.lAttrCountOffset += SIGN_CONST_POOL_LENGTH;
  353. pPara->Sign.lSignAttrOffset += SIGN_CONST_POOL_LENGTH;
  354. pPara->Sign.lEndOfFileOffset += SIGN_CONST_POOL_LENGTH;
  355. // Increment u2 constant_pool_count and update in file
  356. pPara->Sign.wConstPoolCount++;
  357. ToJavaU2(pPara->Sign.wConstPoolCount, rgb);
  358. if (!SeekAndWriteFile(hFile, CONST_POOL_COUNT_OFFSET, rgb, 2))
  359. return FALSE;
  360. // Add constant pool entry for the sign attr name and update in file
  361. rgb[0] = CONSTANT_Utf8;
  362. ToJavaU2(SIGN_ATTR_NAME_LENGTH, &rgb[1]);
  363. memcpy(&rgb[1+2], rgchSignAttrName, SIGN_ATTR_NAME_LENGTH);
  364. if (!SeekAndWriteFile(hFile, pPara->Sign.lSignConstPoolOffset, rgb,
  365. SIGN_CONST_POOL_LENGTH))
  366. return FALSE;
  367. }
  368. if (pPara->Sign.dwSignAttrLength == 0) {
  369. // Add a new attribute for the signed data. The attribute will
  370. // be added at the end of the file.
  371. assert(pPara->Sign.lSignAttrOffset == pPara->Sign.lEndOfFileOffset);
  372. pPara->Sign.lEndOfFileOffset += ATTR_HDR_LENGTH + cbSignedData;
  373. // Increment u2 attribute_count and update in file
  374. BYTE rgb[2];
  375. pPara->Sign.wAttrCount++;
  376. ToJavaU2(pPara->Sign.wAttrCount, rgb);
  377. if (!SeekAndWriteFile(hFile, pPara->Sign.lAttrCountOffset, rgb, 2))
  378. return FALSE;
  379. } else {
  380. // The file already has a signed data attribute.
  381. // If its length is different from the new signed data
  382. // then, the bytes that follow the attribute will
  383. // need to be shifted by the difference in length of the old and new
  384. // signed data
  385. LONG lbShift = cbSignedData - pPara->Sign.dwSignAttrLength;
  386. if (lbShift != 0) {
  387. if (!JavaShiftFileBytes(
  388. pPara->Func.hFile,
  389. pPara->rgbCache,
  390. sizeof(pPara->rgbCache),
  391. pPara->Sign.lSignAttrOffset +
  392. (ATTR_HDR_LENGTH + pPara->Sign.dwSignAttrLength),
  393. pPara->Sign.lEndOfFileOffset,
  394. lbShift))
  395. return FALSE;
  396. pPara->Sign.lEndOfFileOffset += lbShift;
  397. }
  398. }
  399. pPara->Sign.dwSignAttrLength = cbSignedData;
  400. {
  401. // Update the file with the signed data attribute
  402. BYTE rgb[ATTR_HDR_LENGTH];
  403. DWORD cbWritten;
  404. ToJavaU2(pPara->Sign.wSignConstPoolIndex, rgb); // u2 attribute_name
  405. ToJavaU4(cbSignedData, &rgb[2]); // u4 attribute_length
  406. if (!SeekAndWriteFile(hFile, pPara->Sign.lSignAttrOffset, rgb,
  407. ATTR_HDR_LENGTH))
  408. return FALSE;
  409. if (!WriteFile(hFile, pbSignedData, cbSignedData, &cbWritten, NULL) ||
  410. cbWritten != cbSignedData)
  411. return FALSE;
  412. }
  413. // Set end of file
  414. if (0xFFFFFFFF == SetFilePointer(
  415. hFile,
  416. pPara->Sign.lEndOfFileOffset,
  417. NULL, // lpDistanceToMoveHigh
  418. FILE_BEGIN))
  419. return FALSE;
  420. return SetEndOfFile(hFile);
  421. }
  422. //+-------------------------------------------------------------------------
  423. // Reads and optionally digests the Java Class file. Locates the signed data.
  424. //--------------------------------------------------------------------------
  425. static
  426. BOOL
  427. ProcessJavaClassFile(
  428. PJAVA_PARA pPara,
  429. BOOL fInit
  430. )
  431. {
  432. char rgchTmpSignAttrName[SIGN_ATTR_NAME_LENGTH];
  433. WORD wLength;
  434. DWORD dwLength;
  435. WORD wCount;
  436. WORD wConstPoolCount;
  437. WORD wConstPoolIndex;
  438. WORD wSignConstPoolIndex;
  439. WORD wAttrCount;
  440. WORD wAttrIndex;
  441. WORD wAttrName;
  442. WORD wSignAttrIndex;
  443. LONG lAddConstPoolOffset;
  444. int i;
  445. memset(&pPara->Read, 0, sizeof(pPara->Read));
  446. pPara->Read.fResult = TRUE;
  447. if (0xFFFFFFFF == SetFilePointer(
  448. pPara->Func.hFile,
  449. 0, // lDistanceToMove
  450. NULL, // lpDistanceToMoveHigh
  451. FILE_BEGIN))
  452. return FALSE;
  453. if (fInit) {
  454. memset(&pPara->Digest, 0, sizeof(pPara->Digest));
  455. memset(&pPara->Sign, 0, sizeof(pPara->Sign));
  456. }
  457. // Default is to be digested. We'll disable where appropriate. Note,
  458. // skipped bytes are still digested.
  459. pPara->Digest.fDisableDigest = FALSE;
  460. // Read / skip the fields at the beginning of the class file
  461. if (ReadJavaU4(pPara) != JAVA_MAGIC)
  462. { // u4 magic
  463. SetLastError(ERROR_BAD_FORMAT);
  464. return FALSE;
  465. }
  466. SkipJavaBytes(pPara, 2 + 2); // u2 minor_version
  467. // u2 major_version
  468. pPara->Digest.fDisableDigest = TRUE;
  469. wConstPoolCount = ReadJavaU2(pPara); // u2 constant_pool_count
  470. pPara->Digest.fDisableDigest = FALSE;
  471. // For fInit, wSignConstPoolIndex has already been zeroed
  472. wSignConstPoolIndex = pPara->Sign.wSignConstPoolIndex;
  473. // Iterate through the constant pools. Don't digest the constant pool
  474. // containing the _digital_signature_ name (wSignConstPoolIndex).
  475. // For fInit, find the last "_digital_signature_".
  476. //
  477. // Note: constant pool index 0 isn't stored in the file.
  478. wConstPoolIndex = 1;
  479. while (wConstPoolIndex < wConstPoolCount) {
  480. BYTE bTag;
  481. if (wConstPoolIndex == wSignConstPoolIndex)
  482. pPara->Digest.fDisableDigest = TRUE;
  483. bTag = ReadJavaU1(pPara);
  484. switch (bTag) {
  485. case CONSTANT_Utf8:
  486. wLength = ReadJavaU2(pPara);
  487. if (fInit && wLength == SIGN_ATTR_NAME_LENGTH) {
  488. ReadJavaBytes(pPara, (BYTE *) rgchTmpSignAttrName,
  489. SIGN_ATTR_NAME_LENGTH);
  490. if (memcmp(rgchSignAttrName, rgchTmpSignAttrName,
  491. SIGN_ATTR_NAME_LENGTH) == 0) {
  492. wSignConstPoolIndex = wConstPoolIndex;
  493. pPara->Sign.lSignConstPoolOffset =
  494. pPara->Read.lFileOffset - SIGN_CONST_POOL_LENGTH;
  495. }
  496. } else
  497. SkipJavaBytes(pPara, wLength);
  498. break;
  499. case CONSTANT_Unicode:
  500. wLength = ReadJavaU2(pPara);
  501. SkipJavaBytes(pPara, ((DWORD) wLength) * 2);
  502. break;
  503. case CONSTANT_Integer:
  504. case CONSTANT_Float:
  505. case CONSTANT_Long:
  506. case CONSTANT_Double:
  507. case CONSTANT_Class:
  508. case CONSTANT_String:
  509. case CONSTANT_Fieldref:
  510. case CONSTANT_Methodref:
  511. case CONSTANT_InterfaceMethodref:
  512. case CONSTANT_NameAndType:
  513. SkipJavaBytes(pPara, rgConstPoolLength[bTag]);
  514. break;
  515. default:
  516. SetLastError(ERROR_BAD_FORMAT);
  517. return FALSE;
  518. }
  519. pPara->Digest.fDisableDigest = FALSE;
  520. if (bTag == CONSTANT_Long || bTag == CONSTANT_Double)
  521. wConstPoolIndex += 2;
  522. else
  523. wConstPoolIndex++;
  524. }
  525. if (fInit) {
  526. lAddConstPoolOffset = pPara->Read.lFileOffset;
  527. if (wSignConstPoolIndex == 0) {
  528. // Didn't find a constant pool for the digital_signature. Update
  529. // with where it will need to be added
  530. wSignConstPoolIndex = wConstPoolCount;
  531. pPara->Sign.lSignConstPoolOffset = lAddConstPoolOffset;
  532. }
  533. }
  534. // Globble up and hash the bytes until we reach the attributes which are
  535. // at the end of the file.
  536. SkipJavaBytes(pPara, 2 + 2 + 2); // u2 access_flags
  537. // u2 this_class
  538. // u2 super_class
  539. wCount = ReadJavaU2(pPara); // u2 interfaces_count
  540. // u2 interfaces[interfaces_count]
  541. SkipJavaBytes(pPara, ((DWORD) wCount) * 2);
  542. // Since fields and methods have identical class file storage, do this
  543. // twice.
  544. i = 2;
  545. while (i--) {
  546. wCount = ReadJavaU2(pPara); // u2 fields_count | methods_count
  547. while (wCount--) {
  548. SkipJavaBytes(pPara, 2 + 2 + 2); // u2 access_flags
  549. // u2 name_index
  550. // u2 signature_index
  551. wAttrCount = ReadJavaU2(pPara); // u2 attributes_count
  552. while (wAttrCount--) {
  553. SkipJavaBytes(pPara, 2); // u2 attribute_name
  554. dwLength = ReadJavaU4(pPara); // u4 attribute_length
  555. SkipJavaBytes(pPara, dwLength); // u1 info[attribute_length]
  556. }
  557. }
  558. }
  559. // Finally, the attributes. This is where the signed data is
  560. pPara->Sign.lAttrCountOffset = pPara->Read.lFileOffset;
  561. pPara->Digest.fDisableDigest = TRUE;
  562. wAttrCount = ReadJavaU2(pPara); // u2 attributes_count
  563. pPara->Digest.fDisableDigest = FALSE;
  564. if (fInit) {
  565. pPara->Sign.wAttrCount = wAttrCount;
  566. wSignAttrIndex = 0xFFFF;
  567. } else
  568. wSignAttrIndex = pPara->Sign.wSignAttrIndex;
  569. for (wAttrIndex = 0; wAttrIndex < wAttrCount; wAttrIndex++) {
  570. if (wAttrIndex == wSignAttrIndex)
  571. pPara->Digest.fDisableDigest = TRUE;
  572. wAttrName = ReadJavaU2(pPara);
  573. dwLength = ReadJavaU4(pPara); // u4 attribute_length
  574. SkipJavaBytes(pPara, dwLength); // u1 info[attribute_length]
  575. if (fInit && wAttrName == wSignConstPoolIndex && dwLength > 0 &&
  576. wSignConstPoolIndex < wConstPoolCount) {
  577. wSignAttrIndex = wAttrIndex;
  578. pPara->Sign.lSignAttrOffset =
  579. pPara->Read.lFileOffset - (ATTR_HDR_LENGTH + dwLength);
  580. pPara->Sign.dwSignAttrLength = dwLength;
  581. }
  582. pPara->Digest.fDisableDigest = FALSE;
  583. }
  584. if (fInit) {
  585. if (wSignAttrIndex == 0xFFFF) {
  586. // Didn't find an attribute for the digital_signature. Update
  587. // with where it will need to be added
  588. wSignAttrIndex = wAttrCount;
  589. pPara->Sign.lSignAttrOffset = pPara->Read.lFileOffset;
  590. // Also, force us to use a new const pool for the name of the
  591. // attribute
  592. wSignConstPoolIndex = wConstPoolCount;
  593. pPara->Sign.lSignConstPoolOffset = lAddConstPoolOffset;
  594. }
  595. pPara->Sign.wSignConstPoolIndex = wSignConstPoolIndex;
  596. pPara->Sign.wConstPoolCount = wConstPoolCount;
  597. pPara->Sign.wSignAttrIndex = wSignAttrIndex;
  598. pPara->Sign.lEndOfFileOffset = pPara->Read.lFileOffset;
  599. }
  600. // Now check if we got any hash or file errors while processing the file
  601. return pPara->Read.fResult;
  602. }
  603. //+-------------------------------------------------------------------------
  604. // Digest the appropriate bytes from a java file, for a digital signature.
  605. //--------------------------------------------------------------------------
  606. BOOL
  607. JavaGetDigestStream(
  608. IN HANDLE FileHandle,
  609. IN DWORD DigestLevel,
  610. IN DIGEST_FUNCTION DigestFunction,
  611. IN DIGEST_HANDLE DigestHandle
  612. )
  613. {
  614. BOOL fRet;
  615. JAVA_PARA Para;
  616. memset( &Para.Func, 0, sizeof(Para.Func));
  617. assert( DigestLevel == 0);
  618. Para.Func.hFile = FileHandle;
  619. if (!ProcessJavaClassFile( &Para, TRUE))
  620. goto ProcessJavaClassFileTrueError;
  621. Para.Digest.pfnDigestData = DigestFunction;
  622. Para.Digest.hDigestData = DigestHandle;
  623. if (!ProcessJavaClassFile( &Para, FALSE))
  624. goto ProcessJavaClassFileFalseError;
  625. fRet = TRUE;
  626. CommonReturn:
  627. if (Para.Func.pbSignedData)
  628. ShpFree( Para.Func.pbSignedData);
  629. return fRet;
  630. ErrorReturn:
  631. fRet = FALSE;
  632. goto CommonReturn;
  633. TRACE_ERROR_EX(DBG_SS,ProcessJavaClassFileTrueError)
  634. TRACE_ERROR_EX(DBG_SS,ProcessJavaClassFileFalseError)
  635. }
  636. //+-------------------------------------------------------------------------
  637. // Add a digital signature to a java file.
  638. //--------------------------------------------------------------------------
  639. BOOL
  640. JavaAddCertificate(
  641. IN HANDLE FileHandle,
  642. IN LPWIN_CERTIFICATE Certificate,
  643. OUT PDWORD Index
  644. )
  645. {
  646. BOOL fRet;
  647. JAVA_PARA Para;
  648. memset( &Para.Func, 0, sizeof(Para.Func));
  649. Para.Func.hFile = FileHandle;
  650. if (!ProcessJavaClassFile( &Para, TRUE))
  651. goto ProcessJavaClassFileTrueError;
  652. if (!SetSignedDataIntoJavaClassFile(
  653. (HSHPSIGNFILE)&Para,
  654. (PBYTE)&(Certificate->bCertificate),
  655. Certificate->dwLength - OFFSETOF(WIN_CERTIFICATE,bCertificate)))
  656. goto SetSignedDataIntoJavaClassFileError;
  657. fRet = TRUE;
  658. CommonReturn:
  659. if (Para.Func.pbSignedData)
  660. ShpFree( Para.Func.pbSignedData);
  661. return fRet;
  662. ErrorReturn:
  663. fRet = FALSE;
  664. goto CommonReturn;
  665. TRACE_ERROR_EX(DBG_SS,ProcessJavaClassFileTrueError)
  666. TRACE_ERROR_EX(DBG_SS,SetSignedDataIntoJavaClassFileError)
  667. }
  668. //+-------------------------------------------------------------------------
  669. // Remove a digital signature from a java file.
  670. //--------------------------------------------------------------------------
  671. BOOL
  672. JavaRemoveCertificate(
  673. IN HANDLE FileHandle,
  674. IN DWORD Index
  675. )
  676. {
  677. return FALSE;
  678. }
  679. //+-------------------------------------------------------------------------
  680. // Enum the digital signatures in a java file.
  681. //--------------------------------------------------------------------------
  682. BOOL
  683. JavaEnumerateCertificates(
  684. IN HANDLE FileHandle,
  685. IN WORD TypeFilter,
  686. OUT PDWORD CertificateCount,
  687. IN OUT PDWORD Indices OPTIONAL,
  688. IN OUT DWORD IndexCount OPTIONAL
  689. )
  690. {
  691. return FALSE;
  692. }
  693. //+-------------------------------------------------------------------------
  694. // Get a digital signature from a java file.
  695. //--------------------------------------------------------------------------
  696. static
  697. BOOL
  698. I_JavaGetCertificate(
  699. IN HANDLE FileHandle,
  700. IN DWORD CertificateIndex,
  701. OUT LPWIN_CERTIFICATE Certificate,
  702. IN OUT OPTIONAL PDWORD RequiredLength
  703. )
  704. {
  705. BOOL fRet;
  706. JAVA_PARA Para;
  707. memset( &Para.Func, 0, sizeof(Para.Func));
  708. BYTE *pbSignedData = NULL;
  709. DWORD cbSignedData;
  710. DWORD cbCert;
  711. DWORD dwError;
  712. if (CertificateIndex != 0)
  713. goto IndexNonZeroError;
  714. Para.Func.hFile = FileHandle;
  715. if (!ProcessJavaClassFile( &Para, TRUE))
  716. goto ProcessJavaClassFileTrueError;
  717. if (!GetSignedDataFromJavaClassFile(
  718. (HSHPSIGNFILE)&Para,
  719. &pbSignedData,
  720. &cbSignedData))
  721. goto GetSignedDataFromJavaClassFileError;
  722. cbCert = OFFSETOF(WIN_CERTIFICATE,bCertificate) + cbSignedData;
  723. dwError = 0;
  724. __try {
  725. if (RequiredLength) {
  726. // RequiredLength non-NULL only if getting cert data
  727. if (*RequiredLength < cbCert) {
  728. *RequiredLength = cbCert;
  729. dwError = ERROR_INSUFFICIENT_BUFFER;
  730. } else {
  731. memcpy( Certificate->bCertificate, pbSignedData, cbSignedData);
  732. }
  733. }
  734. if (dwError == 0) {
  735. Certificate->dwLength = cbCert;
  736. Certificate->wRevision = WIN_CERT_REVISION_1_0;
  737. Certificate->wCertificateType = WIN_CERT_TYPE_PKCS_SIGNED_DATA;
  738. }
  739. } __except(EXCEPTION_EXECUTE_HANDLER) {
  740. dwError = ERROR_INVALID_PARAMETER;
  741. }
  742. if (dwError) {
  743. SetLastError( dwError);
  744. fRet = FALSE;
  745. } else {
  746. fRet = TRUE;
  747. }
  748. CommonReturn:
  749. ShpFree( Para.Func.pbSignedData);
  750. return fRet;
  751. ErrorReturn:
  752. fRet = FALSE;
  753. goto CommonReturn;
  754. TRACE_ERROR_EX(DBG_SS,IndexNonZeroError)
  755. TRACE_ERROR_EX(DBG_SS,ProcessJavaClassFileTrueError)
  756. TRACE_ERROR_EX(DBG_SS,GetSignedDataFromJavaClassFileError)
  757. }
  758. //+-------------------------------------------------------------------------
  759. // Get a digital signature from a java file.
  760. //--------------------------------------------------------------------------
  761. BOOL
  762. JavaGetCertificateData(
  763. IN HANDLE FileHandle,
  764. IN DWORD CertificateIndex,
  765. OUT LPWIN_CERTIFICATE Certificate,
  766. IN OUT PDWORD RequiredLength
  767. )
  768. {
  769. BOOL fRet;
  770. if (RequiredLength == NULL)
  771. goto RequiredLengthNullError;
  772. fRet = I_JavaGetCertificate(
  773. FileHandle,
  774. CertificateIndex,
  775. Certificate,
  776. RequiredLength
  777. );
  778. CommonReturn:
  779. return fRet;
  780. ErrorReturn:
  781. fRet = FALSE;
  782. goto CommonReturn;
  783. SET_ERROR(RequiredLengthNullError, ERROR_INVALID_PARAMETER)
  784. }
  785. //+-------------------------------------------------------------------------
  786. // Get the header of a digital signature from a java file.
  787. //--------------------------------------------------------------------------
  788. BOOL
  789. JavaGetCertificateHeader(
  790. IN HANDLE FileHandle,
  791. IN DWORD CertificateIndex,
  792. IN OUT LPWIN_CERTIFICATE Certificateheader
  793. )
  794. {
  795. return I_JavaGetCertificate(
  796. FileHandle,
  797. CertificateIndex,
  798. Certificateheader,
  799. NULL
  800. );
  801. }
  802. //+-------------------------------------------------------------------------
  803. // Seeks and writes bytes to file
  804. //--------------------------------------------------------------------------
  805. BOOL
  806. SeekAndWriteFile(
  807. IN HANDLE hFile,
  808. IN DWORD lFileOffset,
  809. IN BYTE *pb,
  810. IN DWORD cb
  811. )
  812. {
  813. DWORD cbWritten;
  814. if (0xFFFFFFFF == SetFilePointer(
  815. hFile,
  816. lFileOffset,
  817. NULL, // lpDistanceToMoveHigh
  818. FILE_BEGIN))
  819. return FALSE;
  820. if (!WriteFile(hFile, pb, cb, &cbWritten, NULL) || cbWritten != cb)
  821. return FALSE;
  822. return TRUE;
  823. }
  824. //+-------------------------------------------------------------------------
  825. // Seeks and reads bytes from file
  826. //--------------------------------------------------------------------------
  827. BOOL
  828. SeekAndReadFile(
  829. IN HANDLE hFile,
  830. IN DWORD lFileOffset,
  831. OUT BYTE *pb,
  832. IN DWORD cb
  833. )
  834. {
  835. DWORD cbRead;
  836. if (0xFFFFFFFF == SetFilePointer(
  837. hFile,
  838. lFileOffset,
  839. NULL, // lpDistanceToMoveHigh
  840. FILE_BEGIN))
  841. return FALSE;
  842. if (!ReadFile(hFile, pb, cb, &cbRead, NULL) || cbRead != cb)
  843. return FALSE;
  844. return TRUE;
  845. }