Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

380 lines
9.9 KiB

  1. //-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1995 - 1999
  6. //
  7. // File: tcrack.cpp
  8. //
  9. // Contents: API testing of CryptEncodeObject/CryptDecodeObject.
  10. //
  11. // History: 29-January-97 xiaohs created
  12. //
  13. //--------------------------------------------------------------------------
  14. #include "global.hxx"
  15. //--------------------------------------------------------------------------
  16. // See if the sequence "81 7f" is in the BLOB. If it is, we need to fix it
  17. //--------------------------------------------------------------------------
  18. BOOL BadCert(DWORD cbEncoded, BYTE *pbEncoded)
  19. {
  20. DWORD iIndex=0;
  21. DWORD iLimit=cbEncoded-2;
  22. BYTE rgByte[2];
  23. assert(pbEncoded);
  24. memset(rgByte, 0, 2);
  25. //set the rgByte to be the patter of 0x81 0x7F, which is 10000001 and 01111111,
  26. //whic his 129 and 127 in decimal
  27. rgByte[0]=rgByte[0]|129;
  28. rgByte[1]=rgByte[1]|127;
  29. for(iIndex=0;iIndex<=iLimit;iIndex++)
  30. {
  31. if(memcmp(rgByte,&(pbEncoded[iIndex]),2)==0)
  32. return TRUE;
  33. }
  34. return FALSE;
  35. }
  36. //--------------------------------------------------------------------------
  37. // Copy the BLOBs
  38. //--------------------------------------------------------------------------
  39. void SetData(DWORD cbNewData, BYTE *pbNewData,
  40. DWORD *pcbOldData, BYTE **ppbOldData)
  41. {
  42. assert(pcbOldData);
  43. assert(ppbOldData);
  44. *pcbOldData=cbNewData;
  45. *ppbOldData=pbNewData;
  46. }
  47. ///////////////////////////////////////////////////////////////////////////
  48. //Certificate Manipulation Functions
  49. //--------------------------------------------------------------------------
  50. // This is the functions
  51. //--------------------------------------------------------------------------
  52. BOOL Fix7FCert(DWORD cbEncoded, BYTE *pbEncoded, DWORD *pcbEncoded,
  53. BYTE **ppbEncoded)
  54. {
  55. //init
  56. *pcbEncoded=0;
  57. *ppbEncoded=NULL;
  58. if(!BadCert(cbEncoded, pbEncoded))
  59. return TRUE;
  60. if(DecodeX509_CERT(cbEncoded, pbEncoded,pcbEncoded,
  61. ppbEncoded))
  62. return TRUE;
  63. else
  64. {
  65. //release the memory
  66. SAFE_FREE(*ppbEncoded)
  67. *ppbEncoded=NULL;
  68. *pcbEncoded=0;
  69. return FALSE;
  70. }
  71. }
  72. //--------------------------------------------------------------------------
  73. // A general routine to encode a struct based on lpszStructType
  74. //--------------------------------------------------------------------------
  75. BOOL EncodeStruct(LPCSTR lpszStructType, void *pStructInfo,DWORD *pcbEncoded,
  76. BYTE **ppbEncoded)
  77. {
  78. BOOL fSucceeded=FALSE;
  79. DWORD cbEncoded=NULL;
  80. //init
  81. *pcbEncoded=0;
  82. *ppbEncoded=NULL;
  83. assert(lpszStructType);
  84. assert(pStructInfo);
  85. //length only calculation
  86. TESTC(CryptEncodeObject(CRYPT_ENCODE_TYPE,lpszStructType, pStructInfo,NULL,
  87. &cbEncoded),TRUE)
  88. //the struct has to be more than 0 byte
  89. assert(cbEncoded);
  90. //allocate the correct amount of memory
  91. *ppbEncoded=(BYTE *)SAFE_ALLOC(cbEncoded);
  92. CHECK_POINTER(*ppbEncoded);
  93. //Encode the strcut with *pcbEncoded == the correct length
  94. *pcbEncoded=cbEncoded;
  95. //Encode the struct
  96. TESTC(CryptEncodeObject(CRYPT_ENCODE_TYPE,lpszStructType,pStructInfo,*ppbEncoded,
  97. pcbEncoded),TRUE)
  98. fSucceeded=TRUE;
  99. TCLEANUP:
  100. return fSucceeded;
  101. }
  102. //--------------------------------------------------------------------------
  103. // A general routine to decode a BLOB based on lpszStructType
  104. //
  105. //--------------------------------------------------------------------------
  106. BOOL DecodeBLOB(LPCSTR lpszStructType,DWORD cbEncoded, BYTE *pbEncoded,
  107. DWORD *pcbStructInfo, void **ppvStructInfo)
  108. {
  109. BOOL fSucceeded=FALSE;
  110. DWORD cbStructInfo=0;
  111. //init
  112. *pcbStructInfo=0;
  113. *ppvStructInfo=NULL;
  114. assert(lpszStructType);
  115. assert(pbEncoded);
  116. assert(cbEncoded);
  117. //Decode. Length Only Calculation
  118. TESTC(CryptDecodeObject(CRYPT_ENCODE_TYPE,lpszStructType,pbEncoded,cbEncoded,
  119. CRYPT_DECODE_FLAG,NULL,&cbStructInfo),TRUE)
  120. //the struct has to be more than 0 byte
  121. assert(cbStructInfo);
  122. *ppvStructInfo=(BYTE *)SAFE_ALLOC(cbStructInfo);
  123. CHECK_POINTER(*ppvStructInfo);
  124. //Decode the BLOB with *pcbStructInfo==correct length
  125. *pcbStructInfo=cbStructInfo;
  126. TESTC(CryptDecodeObject(CRYPT_ENCODE_TYPE,lpszStructType,pbEncoded,cbEncoded,
  127. CRYPT_DECODE_FLAG,*ppvStructInfo,pcbStructInfo),TRUE)
  128. fSucceeded=TRUE;
  129. TCLEANUP:
  130. return fSucceeded;
  131. }
  132. //--------------------------------------------------------------------------
  133. // Decode X509_CERT BLOBs
  134. //
  135. //--------------------------------------------------------------------------
  136. BOOL DecodeX509_CERT(DWORD cbEncoded, BYTE *pbEncoded,DWORD *pcbEncoded,
  137. BYTE **ppbEncoded)
  138. {
  139. BOOL fSucceeded=FALSE;
  140. DWORD cbStructInfo=0;
  141. void *pStructInfo=NULL;
  142. LPCSTR lpszStructType=NULL;
  143. DWORD cbToBeSigned=0;
  144. BYTE *pbToBeSigned=NULL;
  145. DWORD cbOldSigned=0;
  146. BYTE *pbOldSigned=NULL;
  147. //init
  148. lpszStructType=X509_CERT;
  149. //Decode the encoded BLOB
  150. TESTC(DecodeBLOB(lpszStructType,cbEncoded, pbEncoded,&cbStructInfo,
  151. &pStructInfo),TRUE)
  152. //Further Decode the X509_CERT_TO_BE_SIGNED
  153. //Notice we should use the original cbData and pbData passed in for Decode
  154. //but use ToBeSigned in CERT_SIGNED_CONTENT_INFO for encode purpose
  155. TESTC(DecodeX509_CERT_TO_BE_SIGNED(cbEncoded,
  156. pbEncoded,&cbToBeSigned,&pbToBeSigned),TRUE);
  157. //copy the new encoded BLOB
  158. SetData((((PCERT_SIGNED_CONTENT_INFO)pStructInfo)->ToBeSigned).cbData,
  159. (((PCERT_SIGNED_CONTENT_INFO)pStructInfo)->ToBeSigned).pbData,
  160. &cbOldSigned, &pbOldSigned);
  161. SetData(cbToBeSigned, pbToBeSigned,
  162. &((((PCERT_SIGNED_CONTENT_INFO)pStructInfo)->ToBeSigned).cbData),
  163. &((((PCERT_SIGNED_CONTENT_INFO)pStructInfo)->ToBeSigned).pbData));
  164. //if requested, encode the BLOB back to what it was. Make sure no data is lost
  165. //by checking the size of the encoded blob and do a memcmp.
  166. TESTC(EncodeStruct(lpszStructType, pStructInfo,pcbEncoded, ppbEncoded),TRUE);
  167. fSucceeded=TRUE;
  168. TCLEANUP:
  169. SetData(cbOldSigned, pbOldSigned,
  170. &((((PCERT_SIGNED_CONTENT_INFO)pStructInfo)->ToBeSigned).cbData),
  171. &((((PCERT_SIGNED_CONTENT_INFO)pStructInfo)->ToBeSigned).pbData));
  172. SAFE_FREE(pStructInfo)
  173. SAFE_FREE(pbToBeSigned)
  174. return fSucceeded;
  175. }
  176. //--------------------------------------------------------------------------
  177. // Decode X509_CERT_TO_BE_SIGNED BLOBs
  178. //
  179. //--------------------------------------------------------------------------
  180. BOOL DecodeX509_CERT_TO_BE_SIGNED(DWORD cbEncoded, BYTE *pbEncoded, DWORD *pcbEncoded,
  181. BYTE **ppbEncoded)
  182. {
  183. BOOL fSucceeded=FALSE;
  184. DWORD cbStructInfo=0;
  185. void *pStructInfo=NULL;
  186. LPCSTR lpszStructType=NULL;
  187. DWORD cbOldIssuer=0;
  188. BYTE *pbOldIssuer=NULL;
  189. DWORD cbIssuer=0;
  190. BYTE *pbIssuer=NULL;
  191. DWORD cbOldSubject=0;
  192. BYTE *pbOldSubject=NULL;
  193. DWORD cbSubject=0;
  194. BYTE *pbSubject=NULL;
  195. //init
  196. lpszStructType=X509_CERT_TO_BE_SIGNED;
  197. //Decode the encoded BLOB
  198. TESTC(DecodeBLOB(lpszStructType,cbEncoded, pbEncoded,&cbStructInfo,
  199. &pStructInfo),TRUE)
  200. //Decode Issuer in CERT_INFO struct
  201. TESTC(DecodeX509_NAME((((PCERT_INFO)pStructInfo)->Issuer).cbData,
  202. (((PCERT_INFO)pStructInfo)->Issuer).pbData,&cbIssuer,&pbIssuer),TRUE)
  203. SetData((((PCERT_INFO)pStructInfo)->Issuer).cbData,
  204. (((PCERT_INFO)pStructInfo)->Issuer).pbData,&cbOldIssuer,&pbOldIssuer);
  205. SetData(cbIssuer, pbIssuer,
  206. &((((PCERT_INFO)pStructInfo)->Issuer).cbData),
  207. &((((PCERT_INFO)pStructInfo)->Issuer).pbData));
  208. //Decode Subject in CERT_INFO struct
  209. TESTC(DecodeX509_NAME((((PCERT_INFO)pStructInfo)->Subject).cbData,
  210. (((PCERT_INFO)pStructInfo)->Subject).pbData,&cbSubject,&pbSubject),TRUE)
  211. SetData((((PCERT_INFO)pStructInfo)->Subject).cbData,
  212. (((PCERT_INFO)pStructInfo)->Subject).pbData,
  213. &cbOldSubject, &pbOldSubject);
  214. SetData(cbSubject, pbSubject,
  215. &((((PCERT_INFO)pStructInfo)->Subject).cbData),
  216. &((((PCERT_INFO)pStructInfo)->Subject).pbData));
  217. //if requested, encode the BLOB back to what it was. Make sure no data is lost
  218. //by checking the size of the encoded blob and do a memcmp.
  219. TESTC(EncodeStruct(lpszStructType, pStructInfo,pcbEncoded,
  220. ppbEncoded),TRUE);
  221. fSucceeded=TRUE;
  222. TCLEANUP:
  223. //copy back the old values
  224. SetData(cbOldSubject, pbOldSubject,
  225. &((((PCERT_INFO)pStructInfo)->Subject).cbData),
  226. &((((PCERT_INFO)pStructInfo)->Subject).pbData));
  227. SetData(cbOldIssuer, pbOldIssuer,
  228. &((((PCERT_INFO)pStructInfo)->Issuer).cbData),
  229. &((((PCERT_INFO)pStructInfo)->Issuer).pbData));
  230. SAFE_FREE(pStructInfo)
  231. SAFE_FREE(pbSubject)
  232. SAFE_FREE(pbIssuer)
  233. return fSucceeded;
  234. }
  235. //--------------------------------------------------------------------------
  236. // Decode X509_NAME BLOBs
  237. //
  238. //--------------------------------------------------------------------------
  239. BOOL DecodeX509_NAME(DWORD cbEncoded, BYTE *pbEncoded, DWORD *pcbEncoded,
  240. BYTE **ppbEncoded)
  241. {
  242. BOOL fSucceeded=FALSE;
  243. DWORD cbStructInfo=0;
  244. void *pStructInfo=NULL;
  245. LPCSTR lpszStructType=NULL;
  246. //init
  247. lpszStructType=X509_NAME;
  248. //Decode the encoded BLOB
  249. TESTC(DecodeBLOB(lpszStructType,cbEncoded, pbEncoded,&cbStructInfo,
  250. &pStructInfo),TRUE)
  251. //if requested, encode the BLOB back to what it was. Make sure no data is lost
  252. //by checking the size of the encoded blob and do a memcmp.
  253. TESTC(EncodeStruct(lpszStructType, pStructInfo,pcbEncoded, ppbEncoded),TRUE);
  254. fSucceeded=TRUE;
  255. TCLEANUP:
  256. SAFE_FREE(pStructInfo)
  257. return fSucceeded;
  258. }