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.

198 lines
7.3 KiB

  1. // AuxContext.cpp -- Auxiliary Provider Context wrapper functor to
  2. // manage allocation of a temporal context to one of the Microsoft
  3. // CSPs (for use as a supplemental CSP).
  4. // (c) Copyright Schlumberger Technology Corp., unpublished work, created
  5. // 1999. This computer program includes Confidential, Proprietary
  6. // Information and is a Trade Secret of Schlumberger Technology Corp. All
  7. // use, disclosure, and/or reproduction is prohibited unless authorized
  8. // in writing. All Rights Reserved.
  9. #include "stdafx.h"
  10. #include <string>
  11. #include <malloc.h> // for _alloca
  12. #include <scuOsExc.h>
  13. #include "AuxContext.h"
  14. #include "Uuid.h"
  15. using namespace std;
  16. /////////////////////////// HELPER /////////////////////////////////
  17. /////////////////////////// PUBLIC /////////////////////////////////
  18. // Types
  19. // C'tors/D'tors
  20. AuxContext::AuxContext()
  21. : m_hcryptprov(0),
  22. m_fDeleteOnDestruct(false),
  23. m_szProvider()
  24. {
  25. // Acquire a context to a "temporal" container to one of the
  26. // Microsoft CSPs for use as an auxiliary CSP. Attempt is first
  27. // made for the strong crypto provider (MS Enhanced CSP). If that
  28. // isn't available (installed), then an attempt is made for the MS
  29. // Base CSP.
  30. // The existence of any objects stored in the acquired container
  31. // is only for the life of this context object (temporal). This
  32. // is implemented by using a feature (as yet undocumented) that
  33. // was added to the Microsoft CSPs to support the notion of
  34. // "temporal" or "memory resident" container. Temporal containers
  35. // are created by acquiring context with a NULL/empty container
  36. // name using the CRYPT_VERIFYCONTEXT flag. These are containers
  37. // whose associated contents (keys, hashes, etc.) are deleted when
  38. // the last context to that container is released. Temporal
  39. // containers are preferred over creating and releasing/deleting
  40. // containers with temporary names so the resources used will be
  41. // freed if the application exists abnormally and not pollute the
  42. // container name space.
  43. // COMPATIBILITY ISSUE: Since temporal containers weren't
  44. // supported by the MS CSP until Windows 2000 Beta 2 (Build 1840),
  45. // a few hurdles are overcome to acheive similar functionality
  46. // using previous versions. It's unclear when temporal containers
  47. // will be supported on W95/98 & NT 4. As a result, two methods
  48. // of acquiring a context to the auxiliary CSP is used.
  49. // For environments that don't support temporal containers, a
  50. // normal context is acquired to a uniquely named container since
  51. // the default container may be used by other
  52. // applications/threads. The CRYPT_VERIFYCONTEXT flag can not be
  53. // used since keys may want to be imported to the temporal
  54. // container and this characteristic isn't support until Windows 2000.
  55. // Upon destruction of the object, the container is deleted along
  56. // with any of its contents just as a first class temporal
  57. // container.
  58. static LPCTSTR const aszCandidateProviders[] = {
  59. MS_ENHANCED_PROV,
  60. MS_DEF_PROV
  61. };
  62. OSVERSIONINFO osVer;
  63. ZeroMemory(&osVer, sizeof osVer);
  64. osVer.dwOSVersionInfoSize = sizeof osVer;
  65. if (!GetVersionEx(&osVer))
  66. throw scu::OsException(GetLastError());
  67. basic_string<unsigned char> sContainerName;
  68. DWORD dwAcquisitionFlags;
  69. if ((VER_PLATFORM_WIN32_WINDOWS == osVer.dwPlatformId) ||
  70. ((VER_PLATFORM_WIN32_NT == osVer.dwPlatformId) &&
  71. (5 > osVer.dwMajorVersion)))
  72. {
  73. m_fDeleteOnDestruct = true;
  74. // Construct a container name that is unique for this thread
  75. static char unsigned const szRootContainerName[] = "SLBCSP-";
  76. sContainerName = szRootContainerName; // prefix for easy debugging
  77. sContainerName.append(Uuid().AsUString());
  78. dwAcquisitionFlags = CRYPT_NEWKEYSET;
  79. }
  80. else
  81. {
  82. m_fDeleteOnDestruct = false;
  83. dwAcquisitionFlags = CRYPT_VERIFYCONTEXT;
  84. }
  85. bool fCandidateFound = false;
  86. for (size_t i = 0;
  87. (i < (sizeof aszCandidateProviders /
  88. sizeof *aszCandidateProviders) && !fCandidateFound); i++)
  89. {
  90. CString csCntrName(sContainerName.c_str());
  91. if (CryptAcquireContext(&m_hcryptprov,
  92. (LPCTSTR)csCntrName,
  93. aszCandidateProviders[i],
  94. PROV_RSA_FULL, dwAcquisitionFlags))
  95. {
  96. fCandidateFound = true;
  97. m_szProvider = aszCandidateProviders[i];
  98. }
  99. }
  100. if (!fCandidateFound)
  101. throw scu::OsException(GetLastError());
  102. }
  103. AuxContext::AuxContext(HCRYPTPROV hcryptprov,
  104. bool fTransferOwnership)
  105. : m_hcryptprov(hcryptprov),
  106. m_fDeleteOnDestruct(fTransferOwnership),
  107. m_szProvider()
  108. {}
  109. AuxContext::~AuxContext()
  110. {
  111. if (0 != m_hcryptprov)
  112. {
  113. if (m_fDeleteOnDestruct)
  114. {
  115. char *pszContainerName = 0;
  116. DWORD dwNameLength;
  117. if (CryptGetProvParam(m_hcryptprov, PP_CONTAINER, NULL,
  118. &dwNameLength, 0))
  119. {
  120. pszContainerName =
  121. static_cast<char *>(_alloca(dwNameLength));
  122. if (!CryptGetProvParam(m_hcryptprov, PP_CONTAINER,
  123. reinterpret_cast<char unsigned *>(pszContainerName),
  124. &dwNameLength, 0))
  125. pszContainerName = 0;
  126. }
  127. if (CryptReleaseContext(m_hcryptprov, 0))
  128. {
  129. if (pszContainerName)
  130. CryptAcquireContext(&m_hcryptprov, (LPCTSTR)pszContainerName,
  131. m_szProvider, PROV_RSA_FULL,
  132. CRYPT_DELETEKEYSET);
  133. }
  134. }
  135. else // Just release the context
  136. {
  137. CryptReleaseContext(m_hcryptprov, 0);
  138. }
  139. }
  140. }
  141. // Operators
  142. HCRYPTPROV
  143. AuxContext::operator()() const
  144. {
  145. return m_hcryptprov;
  146. }
  147. // Operations
  148. // Access
  149. // Predicates
  150. // Static Variables
  151. /////////////////////////// PROTECTED /////////////////////////////////
  152. // C'tors/D'tors
  153. // Operators
  154. // Operations
  155. // Access
  156. // Predicates
  157. // Static Variables
  158. /////////////////////////// PRIVATE /////////////////////////////////
  159. // C'tors/D'tors
  160. // Operators
  161. // Operations
  162. // Access
  163. // Predicates
  164. // Static Variables