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.

307 lines
9.1 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. // FILE : getsig.cpp //
  3. // DESCRIPTION : Crypto API interface //
  4. // AUTHOR : //
  5. // HISTORY : //
  6. // Mar 5 1998 jeffspel //
  7. // //
  8. // Copyright (C) Microsoft Corporation, 1996 - 1999All Rights Reserved //
  9. /////////////////////////////////////////////////////////////////////////////
  10. #include <windows.h>
  11. #include <wincrypt.h>
  12. #include <stdlib.h>
  13. #include <stddef.h>
  14. #include <stdio.h>
  15. // designatred resource for in file signatures
  16. #define CRYPT_SIG_RESOURCE_NUMBER "#666"
  17. /*++
  18. GetCryptSigResourcePtr:
  19. Given hInst, allocs and returns pointers to signature pulled from
  20. resource
  21. Arguments:
  22. IN hInst - Handle to the loaded file
  23. OUT ppbRsrcSig - Signature from the resource
  24. OUT pcbRsrcSig- Length of the signature from the resource
  25. Return Value:
  26. TRUE - Success
  27. FALSE - Error
  28. --*/
  29. BOOL GetCryptSigResourcePtr(
  30. HMODULE hInst,
  31. BYTE **ppbRsrcSig,
  32. DWORD *pcbRsrcSig
  33. )
  34. {
  35. HRSRC hRsrc;
  36. BOOL fRet = FALSE;
  37. // Nab resource handle for our signature
  38. if (NULL == (hRsrc = FindResource(hInst, CRYPT_SIG_RESOURCE_NUMBER,
  39. RT_RCDATA)))
  40. goto Ret;
  41. // get a pointer to the actual signature data
  42. if (NULL == (*ppbRsrcSig = (PBYTE)LoadResource(hInst, hRsrc)))
  43. goto Ret;
  44. // determine the size of the resource
  45. if (0 == (*pcbRsrcSig = SizeofResource(hInst, hRsrc)))
  46. goto Ret;
  47. fRet = TRUE;
  48. Ret:
  49. return fRet;
  50. }
  51. /*++
  52. GetCryptSignatureResource:
  53. Gets the signature from the file resource.
  54. Arguments:
  55. IN szFile - Name of the file to get the signature from
  56. OUT ppbSignature - Signature of the specified provider
  57. OUT pcbSignature- Length of the signature of the specified provider
  58. Return Value:
  59. TRUE - Success
  60. FALSE - Error
  61. --*/
  62. BOOL GetCryptSignatureResource(
  63. IN LPCSTR pszFile,
  64. OUT BYTE **ppbSig,
  65. OUT DWORD *pcbSig
  66. )
  67. {
  68. HMODULE hInst = NULL;
  69. BYTE *pbSig;
  70. DWORD cbTemp = 0;
  71. LPSTR pszDest = NULL;
  72. DWORD cbSig;
  73. BOOL fRet = FALSE;
  74. // expand the path if necessary
  75. if (0 == (cbTemp = ExpandEnvironmentStrings(pszFile, (CHAR *) &pszDest,
  76. cbTemp)))
  77. {
  78. goto Ret;
  79. }
  80. if (NULL == (pszDest = (LPSTR)LocalAlloc(LMEM_ZEROINIT,
  81. (UINT)cbTemp)))
  82. {
  83. goto Ret;
  84. }
  85. if (0 == (cbTemp = ExpandEnvironmentStrings(pszFile, pszDest,
  86. cbTemp)))
  87. {
  88. goto Ret;
  89. }
  90. // Load the file as a datafile
  91. if (NULL == (hInst = LoadLibraryEx(pszDest, NULL, LOAD_LIBRARY_AS_DATAFILE)))
  92. {
  93. goto Ret;
  94. }
  95. if (!GetCryptSigResourcePtr(hInst, &pbSig, &cbSig))
  96. {
  97. goto Ret;
  98. }
  99. *pcbSig = cbSig - (sizeof(DWORD) * 2);
  100. if (NULL == (*ppbSig = (BYTE*)LocalAlloc(LMEM_ZEROINIT, *pcbSig)))
  101. goto Ret;
  102. memcpy(*ppbSig, pbSig + (sizeof(DWORD) * 2), *pcbSig);
  103. fRet = TRUE;
  104. Ret:
  105. if (pszDest)
  106. LocalFree(pszDest);
  107. if (hInst)
  108. FreeLibrary(hInst);
  109. return fRet;
  110. }
  111. #define PROV_INITIAL_REG_PATH "Software\\Microsoft\\Cryptography\\Defaults\\Provider\\"
  112. /*++
  113. CheckForSignatureInRegistry:
  114. Check if signature is in the registry, if so then get it
  115. if it isn't then get the filename for the provider
  116. Arguments:
  117. IN hProv - Handle to the provider to get the signature of
  118. OUT ppbSignature - Signature of the specified provider if in registry
  119. OUT pcbSignature - Length of the signature of the specified provider
  120. if in the registry
  121. OUT pszProvFile - Provider file name if signature is not in registry
  122. OUT pfSigInReg - TRUE if signature is in the registry
  123. Return Value:
  124. TRUE - Success
  125. FALSE - Error
  126. --*/
  127. BOOL CheckForSignatureInRegistry(
  128. IN HCRYPTPROV hProv,
  129. OUT BYTE **ppbSignature,
  130. OUT DWORD *pcbSignature,
  131. OUT LPSTR *ppszProvFile,
  132. OUT BOOL *pfSigInReg
  133. )
  134. {
  135. HKEY hRegKey = 0;
  136. LPSTR pszProvName = NULL;
  137. DWORD cbProvName;
  138. LPSTR pszFullRegPath = NULL;
  139. DWORD cbFullRegPath;
  140. DWORD dwType;
  141. DWORD cbData;
  142. BOOL fRet = FALSE;
  143. *pfSigInReg = TRUE;
  144. // get the provider name
  145. if (!CryptGetProvParam(hProv, PP_NAME, NULL, &cbProvName, 0))
  146. goto Ret;
  147. if (NULL == (pszProvName = (LPSTR)LocalAlloc(LMEM_ZEROINIT, cbProvName)))
  148. goto Ret;
  149. if (!CryptGetProvParam(hProv, PP_NAME, (BYTE*)pszProvName,
  150. &cbProvName, 0))
  151. {
  152. goto Ret;
  153. }
  154. // open the registry key of the provider
  155. cbFullRegPath = sizeof(PROV_INITIAL_REG_PATH) + (DWORD)strlen(pszProvName) + 1;
  156. if (NULL == (pszFullRegPath = (LPSTR)LocalAlloc(LMEM_ZEROINIT,
  157. cbFullRegPath)))
  158. {
  159. goto Ret;
  160. }
  161. strcpy(pszFullRegPath, PROV_INITIAL_REG_PATH);
  162. strcat(pszFullRegPath, pszProvName);
  163. if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  164. pszFullRegPath, 0,
  165. KEY_READ, &hRegKey))
  166. goto Ret;
  167. // Check if SigInFile entry is there
  168. // NOTE : this may change in the next couple weeks
  169. if (ERROR_SUCCESS == RegQueryValueEx(hRegKey, "SigInFile", NULL, &dwType,
  170. NULL, &cbData))
  171. {
  172. // get the file name
  173. if (ERROR_SUCCESS != RegQueryValueEx(hRegKey, "Image Path",
  174. NULL, &dwType,
  175. NULL, &cbData))
  176. goto Ret;
  177. if (NULL == (*ppszProvFile = (LPSTR)LocalAlloc(LMEM_ZEROINIT, cbData)))
  178. goto Ret;
  179. if (ERROR_SUCCESS != RegQueryValueEx(hRegKey, "Image Path",
  180. NULL, &dwType,
  181. (BYTE*)*ppszProvFile, &cbData))
  182. goto Ret;
  183. *pfSigInReg = FALSE;
  184. }
  185. else
  186. {
  187. // get signature from registry
  188. if (ERROR_SUCCESS != RegQueryValueEx(hRegKey, "Signature",
  189. NULL, &dwType,
  190. NULL, pcbSignature))
  191. goto Ret;
  192. if (NULL == (*ppbSignature = (BYTE*)LocalAlloc(LMEM_ZEROINIT,
  193. *pcbSignature)))
  194. goto Ret;
  195. if (ERROR_SUCCESS != RegQueryValueEx(hRegKey, "Signature",
  196. NULL, &dwType,
  197. *ppbSignature, pcbSignature))
  198. goto Ret;
  199. }
  200. fRet = TRUE;
  201. Ret:
  202. if (pszProvName)
  203. LocalFree(pszProvName);
  204. if (pszFullRegPath)
  205. LocalFree(pszFullRegPath);
  206. if (hRegKey)
  207. RegCloseKey(hRegKey);
  208. return fRet;
  209. }
  210. /*++
  211. GetSignatureFromHPROV:
  212. Gets the signature of a provider associated with the passed in
  213. HCRYPTPROV.
  214. Arguments:
  215. IN hProv - Handle to the provider to get the signature of
  216. OUT ppbSignature - Signature of the specified provider
  217. OUT pcbSignature- Length of the signature of the specified provider
  218. Return Value:
  219. TRUE - Success
  220. FALSE - Error
  221. --*/
  222. BOOL GetSignatureFromHPROV(
  223. IN HCRYPTPROV hProv,
  224. OUT BYTE **ppbSignature,
  225. DWORD *pcbSignature
  226. )
  227. {
  228. LPSTR pszProvFile = NULL;
  229. BOOL fSigInReg;
  230. BOOL fRet = FALSE;
  231. // Check if signature is in the registry, if so then get it
  232. // if it isn't then get the filename for the provider
  233. if (!CheckForSignatureInRegistry(hProv, ppbSignature, pcbSignature,
  234. &pszProvFile, &fSigInReg))
  235. goto Ret;
  236. if (!fSigInReg)
  237. {
  238. //
  239. // Get the signature from the resource in the file
  240. //
  241. if (!GetCryptSignatureResource(pszProvFile, ppbSignature,
  242. pcbSignature))
  243. {
  244. goto Ret;
  245. }
  246. }
  247. fRet = TRUE;
  248. Ret:
  249. if (pszProvFile)
  250. LocalFree(pszProvFile);
  251. return fRet;
  252. }