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.

241 lines
6.8 KiB

  1. //+-------------------------------------------------------------------------
  2. // File: tgetopus.cpp
  3. //
  4. // Contents: Example code to get OPUS info from an authenticode signed
  5. // file. The OPUS info contains the publisher specified
  6. // program name and more info URL.
  7. //--------------------------------------------------------------------------
  8. #include <windows.h>
  9. #include <wincrypt.h>
  10. #include <wintrust.h>
  11. #include <stdlib.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <memory.h>
  15. //+-------------------------------------------------------------------------
  16. // The returned OPUS info must be freed via LocalFree().
  17. //
  18. // NULL is returned if unable to extract the OPUS info from the file.
  19. // Call GetLastError() to get additional error info.
  20. //
  21. // Interesting fields:
  22. // pOpusInfo->pwszProgramName
  23. // pOpusInfo->pMoreInfo, where normally
  24. // pOpusInfo->pMoreInfo->dwLinkChoice == SPC_URL_LINK_CHOICE
  25. // pOpusInfo->pMoreInfo->pwszUrl
  26. //
  27. //--------------------------------------------------------------------------
  28. PSPC_SP_OPUS_INFO
  29. GetOpusInfoFromSignedFile(
  30. IN LPCWSTR pwszFilename
  31. )
  32. {
  33. DWORD dwLastError = 0;
  34. PSPC_SP_OPUS_INFO pOpusInfo = NULL;
  35. HCRYPTMSG hCryptMsg = NULL;
  36. PCMSG_SIGNER_INFO pSignerInfo = NULL;
  37. DWORD cbInfo;
  38. PCRYPT_ATTRIBUTE pOpusAttr; // not allocated
  39. // Extract the PKCS 7 message from the signed file
  40. if (!CryptQueryObject(
  41. CERT_QUERY_OBJECT_FILE,
  42. (const void *) pwszFilename,
  43. CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
  44. CERT_QUERY_FORMAT_FLAG_BINARY,
  45. 0, // dwFlags
  46. NULL, // pdwMsgAndCertEncodingType
  47. NULL, // pdwContentType
  48. NULL, // pdwFormatType
  49. NULL, // phCertStore
  50. &hCryptMsg,
  51. NULL // ppvContext
  52. ))
  53. goto ExtractPKCS7FromSignedFileError;
  54. // Get the signer info for the first signer. Note, authenticode
  55. // currently only has one signer.
  56. cbInfo = 0;
  57. if (!CryptMsgGetParam(
  58. hCryptMsg,
  59. CMSG_SIGNER_INFO_PARAM,
  60. 0, // dwSignerIndex
  61. NULL, // pvData
  62. &cbInfo
  63. ))
  64. goto GetSignerInfoError;
  65. if (NULL == (pSignerInfo = (PCMSG_SIGNER_INFO) LocalAlloc(LPTR, cbInfo)))
  66. goto OutOfMemory;
  67. if (!CryptMsgGetParam(
  68. hCryptMsg,
  69. CMSG_SIGNER_INFO_PARAM,
  70. 0, // dwSignerIndex
  71. pSignerInfo,
  72. &cbInfo
  73. ))
  74. goto GetSignerInfoError;
  75. // If present, the OPUS info is an authenticated signer attribute
  76. if (NULL == (pOpusAttr = CertFindAttribute(
  77. SPC_SP_OPUS_INFO_OBJID,
  78. pSignerInfo->AuthAttrs.cAttr,
  79. pSignerInfo->AuthAttrs.rgAttr
  80. )) || 0 == pOpusAttr->cValue) {
  81. SetLastError(CRYPT_E_ATTRIBUTES_MISSING);
  82. goto NoOpusAttr;
  83. }
  84. // Simply allocate and decode the OPUS info stored in the above
  85. // authenticated attribute. Note, the returned allocated structure
  86. // must be freed via LocalAlloc()
  87. if (!CryptDecodeObject(
  88. X509_ASN_ENCODING,
  89. SPC_SP_OPUS_INFO_STRUCT,
  90. pOpusAttr->rgValue[0].pbData,
  91. pOpusAttr->rgValue[0].cbData,
  92. CRYPT_DECODE_ALLOC_FLAG,
  93. (void *) &pOpusInfo,
  94. &cbInfo
  95. ))
  96. goto DecodeOpusInfoError;
  97. CommonReturn:
  98. if (hCryptMsg)
  99. CryptMsgClose(hCryptMsg);
  100. if (pSignerInfo)
  101. LocalFree(pSignerInfo);
  102. if (dwLastError)
  103. SetLastError(dwLastError);
  104. return pOpusInfo;
  105. ExtractPKCS7FromSignedFileError:
  106. GetSignerInfoError:
  107. OutOfMemory:
  108. NoOpusAttr:
  109. DecodeOpusInfoError:
  110. goto CommonReturn;
  111. }
  112. void Usage(void)
  113. {
  114. printf("Usage: tgetopus <filename>\n");
  115. }
  116. void PrintLastError(LPCSTR pszMsg)
  117. {
  118. DWORD dwErr = GetLastError();
  119. printf("%s failed => 0x%x (%d) \n", pszMsg, dwErr, dwErr);
  120. }
  121. //+-------------------------------------------------------------------------
  122. // Allocate and convert a multi-byte string to a wide string
  123. //--------------------------------------------------------------------------
  124. LPWSTR AllocAndSzToWsz(LPCSTR psz)
  125. {
  126. size_t cb;
  127. LPWSTR pwsz = NULL;
  128. if (-1 == (cb = mbstowcs( NULL, psz, strlen(psz))))
  129. goto bad_param;
  130. cb += 1; // terminating NULL
  131. if (NULL == (pwsz = (LPWSTR) LocalAlloc(LPTR, cb * sizeof(WCHAR)))) {
  132. PrintLastError("AllocAndSzToWsz");
  133. goto failed;
  134. }
  135. if (-1 == mbstowcs( pwsz, psz, cb))
  136. goto bad_param;
  137. goto common_return;
  138. bad_param:
  139. printf("Bad AllocAndSzToWsz\n");
  140. failed:
  141. if (pwsz) {
  142. LocalFree(pwsz);
  143. pwsz = NULL;
  144. }
  145. common_return:
  146. return pwsz;
  147. }
  148. int _cdecl main(int argc, char * argv[])
  149. {
  150. int iStatus = 0;
  151. LPCSTR pszFilename = NULL; // not allocated
  152. LPWSTR pwszFilename = NULL;
  153. PSPC_SP_OPUS_INFO pOpusInfo = NULL;
  154. while (--argc>0)
  155. {
  156. if (**++argv == '-')
  157. {
  158. switch(argv[0][1])
  159. {
  160. case 'h':
  161. default:
  162. goto BadUsage;
  163. }
  164. } else {
  165. if (pszFilename == NULL)
  166. pszFilename = argv[0];
  167. else {
  168. printf("Too many arguments\n");
  169. goto BadUsage;
  170. }
  171. }
  172. }
  173. if (pszFilename == NULL) {
  174. printf("missing Filename \n");
  175. goto BadUsage;
  176. }
  177. printf("command line: %s\n", GetCommandLine());
  178. if (NULL == (pwszFilename = AllocAndSzToWsz(pszFilename)))
  179. goto ErrorReturn;
  180. if (NULL == (pOpusInfo = GetOpusInfoFromSignedFile(pwszFilename))) {
  181. PrintLastError("GetOpusInfoFromSignedFile");
  182. goto ErrorReturn;
  183. }
  184. if (pOpusInfo->pwszProgramName)
  185. printf("ProgramName:: %S\n", pOpusInfo->pwszProgramName);
  186. else
  187. printf("NO ProgramName\n");
  188. if (pOpusInfo->pMoreInfo &&
  189. SPC_URL_LINK_CHOICE == pOpusInfo->pMoreInfo->dwLinkChoice)
  190. printf("ProgramUrl:: %S\n", pOpusInfo->pMoreInfo->pwszUrl);
  191. else
  192. printf("NO ProgramUrl\n");
  193. printf("Passed\n");
  194. iStatus = 0;
  195. CommonReturn:
  196. if (pwszFilename)
  197. LocalFree(pwszFilename);
  198. if (pOpusInfo)
  199. LocalFree(pOpusInfo);
  200. return iStatus;
  201. ErrorReturn:
  202. iStatus = -1;
  203. printf("Failed\n");
  204. goto CommonReturn;
  205. BadUsage:
  206. Usage();
  207. goto ErrorReturn;
  208. }