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.

351 lines
9.5 KiB

  1. /******************************************************************************
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. main.cpp
  5. Abstract:
  6. This file contains the client program for dealing with script signature.
  7. Revision History:
  8. Davide Massarenti (Dmassare) 04/11/2000
  9. created
  10. ******************************************************************************/
  11. #include "stdafx.h"
  12. #include <iostream>
  13. #include <string>
  14. #include <list>
  15. //////////////////////////////////////////////////////////////////////
  16. static void Usage( int argc ,
  17. LPCWSTR argv[] )
  18. {
  19. wprintf( L"Usage: %s <command> <parameters>\n\n", argv[0] );
  20. wprintf( L"Available commands:\n\n" );
  21. wprintf( L" CREATE <private key file> <public key file>\n" );
  22. wprintf( L" SIGN <private key file> <file to sign> <signature file>\n" );
  23. wprintf( L" VERIFY <public key file> <signed file> <signature file>\n" );
  24. }
  25. ////////////////////////////////////////////////////////////////////////////////
  26. static HRESULT LoadFile( /*[in ]*/ LPCWSTR szFile ,
  27. /*[out]*/ HGLOBAL& hg )
  28. {
  29. __HCP_FUNC_ENTRY( "LoadFile" );
  30. HRESULT hr;
  31. CComPtr<IStream> streamMem;
  32. CComPtr<MPC::FileStream> streamFile;
  33. //
  34. // Create a stream for a file.
  35. //
  36. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &streamFile ));
  37. __MPC_EXIT_IF_METHOD_FAILS(hr, streamFile->InitForRead( szFile ));
  38. //
  39. // Create a memory stream.
  40. //
  41. __MPC_EXIT_IF_METHOD_FAILS(hr, ::CreateStreamOnHGlobal( NULL, FALSE, &streamMem ));
  42. //
  43. // Load the contents in memory.
  44. //
  45. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::BaseStream::TransferData( streamFile, streamMem ));
  46. __MPC_EXIT_IF_METHOD_FAILS(hr, ::GetHGlobalFromStream( streamMem, &hg ));
  47. hr = S_OK;
  48. __HCP_FUNC_CLEANUP;
  49. __HCP_FUNC_EXIT(hr);
  50. }
  51. static HRESULT SaveFile( /*[in]*/ LPCWSTR szFile ,
  52. /*[in]*/ HGLOBAL hg )
  53. {
  54. __HCP_FUNC_ENTRY( "SaveFile" );
  55. HRESULT hr;
  56. CComPtr<IStream> streamMem;
  57. CComPtr<MPC::FileStream> streamFile;
  58. //
  59. // Create a stream for a file.
  60. //
  61. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &streamFile ));
  62. __MPC_EXIT_IF_METHOD_FAILS(hr, streamFile->InitForWrite( szFile ));
  63. //
  64. // Create a memory stream.
  65. //
  66. __MPC_EXIT_IF_METHOD_FAILS(hr, ::CreateStreamOnHGlobal( hg, FALSE, &streamMem ));
  67. //
  68. // Load the contents in memory.
  69. //
  70. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::BaseStream::TransferData( streamMem, streamFile ));
  71. hr = S_OK;
  72. __HCP_FUNC_CLEANUP;
  73. __HCP_FUNC_EXIT(hr);
  74. }
  75. ////////////////////////////////////////////////////////////////////////////////
  76. static HRESULT LoadFileAsString( /*[in ]*/ LPCWSTR szFile ,
  77. /*[out]*/ CComBSTR& bstrData )
  78. {
  79. __HCP_FUNC_ENTRY( "LoadFileAsString" );
  80. HRESULT hr;
  81. HGLOBAL hg = NULL;
  82. DWORD dwLen;
  83. LPWSTR str;
  84. __MPC_EXIT_IF_METHOD_FAILS(hr, LoadFile( szFile, hg ));
  85. dwLen = ::GlobalSize( hg );
  86. bstrData.Attach( ::SysAllocStringLen( NULL, dwLen ) );
  87. ::MultiByteToWideChar( CP_ACP, 0, (LPCSTR)::GlobalLock( hg ), dwLen, bstrData, (dwLen+1)*sizeof(WCHAR) ); bstrData[dwLen] = 0;
  88. hr = S_OK;
  89. __HCP_FUNC_CLEANUP;
  90. if(hg) ::GlobalFree( hg );
  91. __HCP_FUNC_EXIT(hr);
  92. }
  93. static HRESULT SaveFileAsString( /*[in]*/ LPCWSTR szFile ,
  94. /*[in]*/ const CComBSTR& bstrData )
  95. {
  96. __HCP_FUNC_ENTRY( "SaveFileAsString" );
  97. USES_CONVERSION;
  98. HRESULT hr;
  99. DWORD dwLen = ::SysStringLen( bstrData );
  100. HGLOBAL hg = NULL;
  101. __MPC_EXIT_IF_CALL_RETURNS_NULL(hr, (hg = ::GlobalAlloc( GMEM_FIXED, dwLen )));
  102. ::CopyMemory( hg, W2A(bstrData), dwLen );
  103. __MPC_EXIT_IF_METHOD_FAILS(hr, SaveFile( szFile, hg ));
  104. hr = S_OK;
  105. __HCP_FUNC_CLEANUP;
  106. if(hg) ::GlobalFree( hg );
  107. __HCP_FUNC_EXIT(hr);
  108. }
  109. ////////////////////////////////////////////////////////////////////////////////
  110. static HRESULT Create( /*[in]*/ LPCWSTR szPrivateFile ,
  111. /*[in]*/ LPCWSTR szPublicFile )
  112. {
  113. __HCP_FUNC_ENTRY( "Create" );
  114. HRESULT hr;
  115. CPCHCryptKeys key;
  116. CComBSTR bstrPrivate;
  117. CComBSTR bstrPublic;
  118. __MPC_EXIT_IF_METHOD_FAILS(hr, key.CreatePair());
  119. __MPC_EXIT_IF_METHOD_FAILS(hr, key.ExportPair( bstrPrivate, bstrPublic ));
  120. __MPC_EXIT_IF_METHOD_FAILS(hr, SaveFileAsString( szPrivateFile, bstrPrivate ));
  121. __MPC_EXIT_IF_METHOD_FAILS(hr, SaveFileAsString( szPublicFile , bstrPublic ));
  122. hr = S_OK;
  123. __HCP_FUNC_CLEANUP;
  124. __HCP_FUNC_EXIT(hr);
  125. }
  126. static HRESULT Sign( /*[in]*/ LPCWSTR szPrivateFile ,
  127. /*[in]*/ LPCWSTR szDataFile ,
  128. /*[in]*/ LPCWSTR szSignatureFile )
  129. {
  130. __HCP_FUNC_ENTRY( "Sign" );
  131. HRESULT hr;
  132. CPCHCryptKeys key;
  133. CComBSTR bstrPrivate;
  134. CComBSTR bstrSignature;
  135. HGLOBAL hg = NULL;
  136. __MPC_EXIT_IF_METHOD_FAILS(hr, LoadFileAsString( szPrivateFile, bstrPrivate ));
  137. __MPC_EXIT_IF_METHOD_FAILS(hr, LoadFile ( szDataFile , hg ));
  138. __MPC_EXIT_IF_METHOD_FAILS(hr, key.ImportPrivate( bstrPrivate ));
  139. __MPC_EXIT_IF_METHOD_FAILS(hr, key.SignData( bstrSignature, (BYTE*)::GlobalLock( hg ), ::GlobalSize( hg ) ));
  140. __MPC_EXIT_IF_METHOD_FAILS(hr, SaveFileAsString( szSignatureFile, bstrSignature ));
  141. hr = S_OK;
  142. __HCP_FUNC_CLEANUP;
  143. if(hg) ::GlobalFree( hg );
  144. __HCP_FUNC_EXIT(hr);
  145. }
  146. static HRESULT Verify( /*[in]*/ LPCWSTR szPublicFile ,
  147. /*[in]*/ LPCWSTR szDataFile ,
  148. /*[in]*/ LPCWSTR szSignatureFile )
  149. {
  150. __HCP_FUNC_ENTRY( "Sign" );
  151. HRESULT hr;
  152. CPCHCryptKeys key;
  153. CComBSTR bstrPublic;
  154. CComBSTR bstrSignature;
  155. HGLOBAL hg = NULL;
  156. __MPC_EXIT_IF_METHOD_FAILS(hr, LoadFileAsString( szPublicFile , bstrPublic ));
  157. __MPC_EXIT_IF_METHOD_FAILS(hr, LoadFileAsString( szSignatureFile, bstrSignature ));
  158. __MPC_EXIT_IF_METHOD_FAILS(hr, LoadFile ( szDataFile , hg ));
  159. __MPC_EXIT_IF_METHOD_FAILS(hr, key.ImportPublic( bstrPublic ));
  160. hr = key.VerifyData( bstrSignature, (BYTE*)::GlobalLock( hg ), ::GlobalSize( hg ) );
  161. if(FAILED(hr))
  162. {
  163. wprintf( L"Verification failure: 0x%08x\n", hr );
  164. }
  165. else
  166. {
  167. wprintf( L"Verification successful: 0x%08x\n", hr );
  168. }
  169. hr = S_OK;
  170. __HCP_FUNC_CLEANUP;
  171. if(hg) ::GlobalFree( hg );
  172. __HCP_FUNC_EXIT(hr);
  173. }
  174. ////////////////////////////////////////////////////////////////////////////////
  175. static HRESULT ProcessArguments( int argc ,
  176. LPCWSTR argv[] )
  177. {
  178. __HCP_FUNC_ENTRY( "ProcessArguments" );
  179. HRESULT hr;
  180. if(argc < 2) { Usage( argc, argv ); __MPC_SET_ERROR_AND_EXIT(hr, E_FAIL); }
  181. if(!_wcsicmp( argv[1], L"CREATE" ))
  182. {
  183. if(argc < 4) { Usage( argc, argv ); __MPC_SET_ERROR_AND_EXIT(hr, E_FAIL); }
  184. __MPC_EXIT_IF_METHOD_FAILS(hr, Create( argv[2], argv[3] ));
  185. }
  186. if(!_wcsicmp( argv[1], L"SIGN" ))
  187. {
  188. if(argc < 5) { Usage( argc, argv ); __MPC_SET_ERROR_AND_EXIT(hr, E_FAIL); }
  189. __MPC_EXIT_IF_METHOD_FAILS(hr, Sign( argv[2], argv[3], argv[4] ));
  190. }
  191. if(!_wcsicmp( argv[1], L"VERIFY" ))
  192. {
  193. if(argc < 5) { Usage( argc, argv ); __MPC_SET_ERROR_AND_EXIT(hr, E_FAIL); }
  194. __MPC_EXIT_IF_METHOD_FAILS(hr, Verify( argv[2], argv[3], argv[4] ));
  195. }
  196. hr = S_OK;
  197. __HCP_FUNC_CLEANUP;
  198. __HCP_FUNC_EXIT(hr);
  199. }
  200. ////////////////////////////////////////////////////////////////////////////////
  201. int __cdecl wmain( int argc ,
  202. LPCWSTR argv[] )
  203. {
  204. HRESULT hr;
  205. //DebugBreak();
  206. //
  207. // We need to be a single-threaded application, because we are hosting script engines and
  208. // script engines don't like to be called from different threads...
  209. //
  210. if(SUCCEEDED(hr = ::CoInitializeEx( NULL, COINIT_APARTMENTTHREADED )))
  211. {
  212. if(SUCCEEDED(hr = ::CoInitializeSecurity( NULL ,
  213. -1 , // We don't care which authentication service we use.
  214. NULL ,
  215. NULL ,
  216. RPC_C_AUTHN_LEVEL_CONNECT, // We want to identify the callers.
  217. RPC_C_IMP_LEVEL_DELEGATE , // We want to be able to forward the caller's identity.
  218. NULL ,
  219. EOAC_DYNAMIC_CLOAKING , // Let's use the thread token for outbound calls.
  220. NULL )))
  221. {
  222. __MPC_TRACE_INIT();
  223. //
  224. // Process arguments.
  225. //
  226. hr = ProcessArguments( argc, argv );
  227. __MPC_TRACE_TERM();
  228. }
  229. ::CoUninitialize();
  230. }
  231. return FAILED(hr) ? 10 : 0;
  232. }