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.

155 lines
4.0 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: pvkutil.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "global.hxx"
  11. #include "pvkhlpr.h"
  12. //+-------------------------------------------------------------------------
  13. // Get crypto provider to based on either the pvkfile or key container name
  14. //--------------------------------------------------------------------------
  15. HRESULT WINAPI PvkGetCryptProv( IN HWND hwnd,
  16. IN LPCWSTR pwszCaption,
  17. IN LPCWSTR pwszCapiProvider,
  18. IN DWORD dwProviderType,
  19. IN LPCWSTR pwszPvkFile,
  20. IN LPCWSTR pwszKeyContainerName,
  21. IN DWORD *pdwKeySpec,
  22. OUT LPWSTR *ppwszTmpContainer,
  23. OUT HCRYPTPROV *phCryptProv)
  24. {
  25. HANDLE hFile=NULL;
  26. HRESULT hr=E_FAIL;
  27. DWORD dwRequiredKeySpec=0;
  28. //Init
  29. *ppwszTmpContainer=NULL;
  30. *phCryptProv=NULL;
  31. //get the provider handle based on the key container name
  32. if(pwszKeyContainerName)
  33. {
  34. if(!CryptAcquireContextU(phCryptProv,
  35. pwszKeyContainerName,
  36. pwszCapiProvider,
  37. dwProviderType,
  38. 0)) // dwFlags
  39. return SignError();
  40. //try to figure out the key specification
  41. if((*pdwKeySpec)==0)
  42. dwRequiredKeySpec=AT_SIGNATURE;
  43. else
  44. dwRequiredKeySpec=*pdwKeySpec;
  45. //make sure *pdwKeySpec is the correct key spec
  46. HCRYPTKEY hPubKey;
  47. if (CryptGetUserKey(
  48. *phCryptProv,
  49. dwRequiredKeySpec,
  50. &hPubKey
  51. ))
  52. {
  53. CryptDestroyKey(hPubKey);
  54. *pdwKeySpec=dwRequiredKeySpec;
  55. return S_OK;
  56. }
  57. else
  58. {
  59. //we fail is user required another key spec
  60. if((*pdwKeySpec)!=0)
  61. {
  62. // Doesn't have the specified public key
  63. hr=SignError();
  64. CryptReleaseContext(*phCryptProv, 0);
  65. *phCryptProv=NULL;
  66. return hr;
  67. }
  68. //now we try AT_EXCHANGE key
  69. dwRequiredKeySpec=AT_KEYEXCHANGE;
  70. if (CryptGetUserKey(
  71. *phCryptProv,
  72. dwRequiredKeySpec,
  73. &hPubKey
  74. ))
  75. {
  76. CryptDestroyKey(hPubKey);
  77. *pdwKeySpec=dwRequiredKeySpec;
  78. return S_OK;
  79. }
  80. else
  81. {
  82. // Doesn't have the specified public key
  83. hr=SignError();
  84. CryptReleaseContext(*phCryptProv, 0);
  85. *phCryptProv=NULL;
  86. return hr;
  87. }
  88. }
  89. }
  90. //get the providedr handle based on the pvk file name
  91. hFile = CreateFileU(pwszPvkFile,
  92. GENERIC_READ,
  93. FILE_SHARE_READ,
  94. NULL, // lpsa
  95. OPEN_EXISTING,
  96. FILE_ATTRIBUTE_NORMAL,
  97. NULL); // hTemplateFile
  98. if (hFile == INVALID_HANDLE_VALUE)
  99. return SignError();
  100. if(!PvkPrivateKeyAcquireContext(pwszCapiProvider,
  101. dwProviderType,
  102. hFile,
  103. hwnd,
  104. pwszCaption,
  105. pdwKeySpec,
  106. phCryptProv,
  107. ppwszTmpContainer))
  108. {
  109. *phCryptProv=NULL;
  110. hr=SignError();
  111. }
  112. else
  113. hr=S_OK;
  114. CloseHandle(hFile);
  115. return hr;
  116. }
  117. void WINAPI PvkFreeCryptProv(IN HCRYPTPROV hProv,
  118. IN LPCWSTR pwszCapiProvider,
  119. IN DWORD dwProviderType,
  120. IN LPWSTR pwszTmpContainer)
  121. {
  122. if (pwszTmpContainer) {
  123. // Delete the temporary container for the private key from
  124. // the provider
  125. PvkPrivateKeyReleaseContext(hProv,
  126. pwszCapiProvider,
  127. dwProviderType,
  128. pwszTmpContainer);
  129. } else {
  130. if (hProv)
  131. CryptReleaseContext(hProv, 0);
  132. }
  133. }