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.

312 lines
7.7 KiB

  1. /******************************************************************************
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. KeysLib.cpp
  5. Abstract:
  6. This file contains the implementation of the CPCHCryptKeys class,
  7. that is uses to sign and verify trusted scripts.
  8. Revision History:
  9. Davide Massarenti (Dmassare) 04/11/2000
  10. created
  11. ******************************************************************************/
  12. #include "stdafx.h"
  13. /////////////////////////////////////////////////////////////////////////////
  14. CPCHCryptKeys::CPCHCryptKeys()
  15. {
  16. __HCP_FUNC_ENTRY( "CPCHCryptKeys::CPCHCryptKeys" );
  17. m_hCryptProv = NULL; // HCRYPTPROV m_hCryptProv;
  18. m_hKey = NULL; // HCRYPTKEY m_hKey;
  19. }
  20. CPCHCryptKeys::~CPCHCryptKeys()
  21. {
  22. __HCP_FUNC_ENTRY( "CPCHCryptKeys::~CPCHCryptKeys" );
  23. Close();
  24. }
  25. HRESULT CPCHCryptKeys::Close()
  26. {
  27. __HCP_FUNC_ENTRY( "CPCHCryptKeys::Close" );
  28. if(m_hKey)
  29. {
  30. ::CryptDestroyKey( m_hKey ); m_hKey = NULL;
  31. }
  32. if(m_hCryptProv)
  33. {
  34. ::CryptReleaseContext( m_hCryptProv, 0 ); m_hCryptProv = NULL;
  35. }
  36. __HCP_FUNC_EXIT(S_OK);
  37. }
  38. HRESULT CPCHCryptKeys::Init()
  39. {
  40. __HCP_FUNC_ENTRY( "CPCHCryptKeys::Init" );
  41. HRESULT hr;
  42. Close();
  43. if(!::CryptAcquireContext( &m_hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_SILENT ))
  44. {
  45. DWORD dwRes = ::GetLastError();
  46. if(dwRes != NTE_BAD_KEYSET)
  47. {
  48. __MPC_SET_WIN32_ERROR_AND_EXIT(hr, dwRes);
  49. }
  50. //
  51. // Key set doesn't exist, let's create one.
  52. //
  53. __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptAcquireContext( &m_hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET | CRYPT_SILENT ));
  54. }
  55. hr = S_OK;
  56. __MPC_FUNC_CLEANUP;
  57. if(FAILED(hr)) Close();
  58. __MPC_FUNC_EXIT(hr);
  59. }
  60. ////////////////////////////////////////////////////////////////////////////////
  61. HRESULT CPCHCryptKeys::CreatePair()
  62. {
  63. __HCP_FUNC_ENTRY( "CPCHCryptKeys::CreatePair" );
  64. HRESULT hr;
  65. __MPC_EXIT_IF_METHOD_FAILS(hr, Init());
  66. __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptGenKey( m_hCryptProv, AT_SIGNATURE, CRYPT_EXPORTABLE, &m_hKey ));
  67. hr = S_OK;
  68. __HCP_FUNC_CLEANUP;
  69. __HCP_FUNC_EXIT(hr);
  70. }
  71. HRESULT CPCHCryptKeys::ExportPair( /*[out]*/ CComBSTR& bstrPrivate ,
  72. /*[out]*/ CComBSTR& bstrPublic )
  73. {
  74. __HCP_FUNC_ENTRY( "CPCHCryptKeys::ExportPair" );
  75. HRESULT hr;
  76. DWORD dwSize;
  77. HGLOBAL hg = NULL;
  78. __MPC_PARAMCHECK_BEGIN(hr)
  79. __MPC_PARAMCHECK_NOTNULL(m_hKey);
  80. __MPC_PARAMCHECK_END();
  81. ////////////////////////////////////////
  82. //
  83. // Export private/public pair.
  84. //
  85. dwSize = 0;
  86. __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptExportKey( m_hKey, NULL, PRIVATEKEYBLOB, 0, NULL, &dwSize ));
  87. __MPC_EXIT_IF_CALL_RETURNS_NULL(hr, (hg = ::GlobalAlloc( GMEM_FIXED, dwSize )));
  88. __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptExportKey( m_hKey, NULL, PRIVATEKEYBLOB, 0, (BYTE*)hg, &dwSize ));
  89. //
  90. // Convert from blob to string.
  91. //
  92. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertHGlobalToHex( hg, bstrPrivate ));
  93. ::GlobalFree( hg ); hg = NULL;
  94. ////////////////////////////////////////
  95. //
  96. // Export public pair.
  97. //
  98. dwSize = 0;
  99. __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptExportKey( m_hKey, NULL, PUBLICKEYBLOB, 0, NULL, &dwSize ));
  100. __MPC_EXIT_IF_CALL_RETURNS_NULL(hr, (hg = ::GlobalAlloc( GMEM_FIXED, dwSize )));
  101. __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptExportKey( m_hKey, NULL, PUBLICKEYBLOB, 0, (BYTE*)hg, &dwSize ));
  102. //
  103. // Convert from blob to string.
  104. //
  105. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertHGlobalToHex( hg, bstrPublic ));
  106. ////////////////////////////////////////
  107. hr = S_OK;
  108. __HCP_FUNC_CLEANUP;
  109. if(hg) ::GlobalFree( hg );
  110. __HCP_FUNC_EXIT(hr);
  111. }
  112. HRESULT CPCHCryptKeys::ImportPrivate( /*[in] */ const CComBSTR& bstrPrivate )
  113. {
  114. __HCP_FUNC_ENTRY( "CPCHCryptKeys::ImportPrivate" );
  115. HRESULT hr;
  116. HGLOBAL hg = NULL;
  117. __MPC_EXIT_IF_METHOD_FAILS(hr, Init());
  118. //
  119. // Convert from string to blob.
  120. //
  121. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertHexToHGlobal( bstrPrivate, hg ));
  122. __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptImportKey( m_hCryptProv, (BYTE*)hg, ::GlobalSize( hg ), NULL, CRYPT_EXPORTABLE, &m_hKey ));
  123. hr = S_OK;
  124. __HCP_FUNC_CLEANUP;
  125. if(hg) ::GlobalFree( hg );
  126. __HCP_FUNC_EXIT(hr);
  127. }
  128. HRESULT CPCHCryptKeys::ImportPublic( /*[in ]*/ const CComBSTR& bstrPublic )
  129. {
  130. __HCP_FUNC_ENTRY( "CPCHCryptKeys::ImportPublic" );
  131. HRESULT hr;
  132. HGLOBAL hg = NULL;
  133. __MPC_EXIT_IF_METHOD_FAILS(hr, Init());
  134. //
  135. // Convert from string to blob.
  136. //
  137. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertHexToHGlobal( bstrPublic, hg ));
  138. __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptImportKey( m_hCryptProv, (BYTE*)hg, ::GlobalSize( hg ), NULL, 0, &m_hKey ));
  139. hr = S_OK;
  140. __HCP_FUNC_CLEANUP;
  141. if(hg) ::GlobalFree( hg );
  142. __HCP_FUNC_EXIT(hr);
  143. }
  144. HRESULT CPCHCryptKeys::SignData( /*[out]*/ CComBSTR& bstrSignature ,
  145. /*[in ]*/ BYTE* pbData ,
  146. /*[in ]*/ DWORD dwDataLen )
  147. {
  148. __HCP_FUNC_ENTRY( "CPCHCryptKeys::SignData" );
  149. HRESULT hr;
  150. DWORD dwSize = 0;
  151. HGLOBAL hg = NULL;
  152. HCRYPTHASH hHash = NULL;
  153. __MPC_PARAMCHECK_BEGIN(hr)
  154. __MPC_PARAMCHECK_NOTNULL(m_hKey);
  155. __MPC_PARAMCHECK_NOTNULL(pbData);
  156. __MPC_PARAMCHECK_END();
  157. __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptCreateHash( m_hCryptProv, CALG_MD5, 0, 0, &hHash ));
  158. __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptHashData( hHash, pbData, dwDataLen, 0 ));
  159. __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptSignHash( hHash, AT_SIGNATURE, NULL, 0, NULL, &dwSize ));
  160. __MPC_EXIT_IF_CALL_RETURNS_NULL(hr, (hg = ::GlobalAlloc( GMEM_FIXED, dwSize )));
  161. __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptSignHash( hHash, AT_SIGNATURE, NULL, 0, (BYTE*)hg, &dwSize ));
  162. //
  163. // Convert from blob to string.
  164. //
  165. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertHGlobalToHex( hg, bstrSignature ));
  166. ////////////////////////////////////////
  167. hr = S_OK;
  168. __HCP_FUNC_CLEANUP;
  169. if(hg) ::GlobalFree( hg );
  170. if(hHash) ::CryptDestroyHash( hHash );
  171. __HCP_FUNC_EXIT(hr);
  172. }
  173. HRESULT CPCHCryptKeys::VerifyData( /*[in]*/ const CComBSTR& bstrSignature,
  174. /*[in]*/ BYTE* pbData ,
  175. /*[in]*/ DWORD dwDataLen )
  176. {
  177. __HCP_FUNC_ENTRY( "CPCHCryptKeys::VerifyData" );
  178. HRESULT hr;
  179. HGLOBAL hg = NULL;
  180. HCRYPTHASH hHash = NULL;
  181. __MPC_PARAMCHECK_BEGIN(hr)
  182. __MPC_PARAMCHECK_NOTNULL(m_hKey);
  183. __MPC_PARAMCHECK_NOTNULL(pbData);
  184. __MPC_PARAMCHECK_END();
  185. //
  186. // Convert from string to blob.
  187. //
  188. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertHexToHGlobal( bstrSignature, hg ));
  189. __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptCreateHash( m_hCryptProv, CALG_MD5, 0, 0, &hHash ));
  190. __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptHashData( hHash, pbData, dwDataLen, 0 ));
  191. __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptVerifySignature( hHash, (BYTE*)hg, ::GlobalSize( hg ), m_hKey, NULL, 0 ));
  192. ////////////////////////////////////////
  193. hr = S_OK;
  194. __HCP_FUNC_CLEANUP;
  195. if(hg) ::GlobalFree( hg );
  196. if(hHash) ::CryptDestroyHash( hHash );
  197. __HCP_FUNC_EXIT(hr);
  198. }