199 lines
7.3 KiB
C++
199 lines
7.3 KiB
C++
// AuxContext.cpp -- Auxiliary Provider Context wrapper functor to
|
|
// manage allocation of a temporal context to one of the Microsoft
|
|
// CSPs (for use as a supplemental CSP).
|
|
|
|
// (c) Copyright Schlumberger Technology Corp., unpublished work, created
|
|
// 1999. This computer program includes Confidential, Proprietary
|
|
// Information and is a Trade Secret of Schlumberger Technology Corp. All
|
|
// use, disclosure, and/or reproduction is prohibited unless authorized
|
|
// in writing. All Rights Reserved.
|
|
|
|
#include "stdafx.h"
|
|
#include <string>
|
|
|
|
#include <malloc.h> // for _alloca
|
|
|
|
#include <scuOsExc.h>
|
|
|
|
#include "AuxContext.h"
|
|
#include "Uuid.h"
|
|
|
|
using namespace std;
|
|
|
|
/////////////////////////// HELPER /////////////////////////////////
|
|
|
|
/////////////////////////// PUBLIC /////////////////////////////////
|
|
|
|
// Types
|
|
// C'tors/D'tors
|
|
AuxContext::AuxContext()
|
|
: m_hcryptprov(0),
|
|
m_fDeleteOnDestruct(false),
|
|
m_szProvider()
|
|
{
|
|
// Acquire a context to a "temporal" container to one of the
|
|
// Microsoft CSPs for use as an auxiliary CSP. Attempt is first
|
|
// made for the strong crypto provider (MS Enhanced CSP). If that
|
|
// isn't available (installed), then an attempt is made for the MS
|
|
// Base CSP.
|
|
|
|
// The existence of any objects stored in the acquired container
|
|
// is only for the life of this context object (temporal). This
|
|
// is implemented by using a feature (as yet undocumented) that
|
|
// was added to the Microsoft CSPs to support the notion of
|
|
// "temporal" or "memory resident" container. Temporal containers
|
|
// are created by acquiring context with a NULL/empty container
|
|
// name using the CRYPT_VERIFYCONTEXT flag. These are containers
|
|
// whose associated contents (keys, hashes, etc.) are deleted when
|
|
// the last context to that container is released. Temporal
|
|
// containers are preferred over creating and releasing/deleting
|
|
// containers with temporary names so the resources used will be
|
|
// freed if the application exists abnormally and not pollute the
|
|
// container name space.
|
|
|
|
// COMPATIBILITY ISSUE: Since temporal containers weren't
|
|
// supported by the MS CSP until Windows 2000 Beta 2 (Build 1840),
|
|
// a few hurdles are overcome to acheive similar functionality
|
|
// using previous versions. It's unclear when temporal containers
|
|
// will be supported on W95/98 & NT 4. As a result, two methods
|
|
// of acquiring a context to the auxiliary CSP is used.
|
|
|
|
// For environments that don't support temporal containers, a
|
|
// normal context is acquired to a uniquely named container since
|
|
// the default container may be used by other
|
|
// applications/threads. The CRYPT_VERIFYCONTEXT flag can not be
|
|
// used since keys may want to be imported to the temporal
|
|
// container and this characteristic isn't support until Windows 2000.
|
|
// Upon destruction of the object, the container is deleted along
|
|
// with any of its contents just as a first class temporal
|
|
// container.
|
|
|
|
static LPCTSTR const aszCandidateProviders[] = {
|
|
MS_ENHANCED_PROV,
|
|
MS_DEF_PROV
|
|
};
|
|
|
|
OSVERSIONINFO osVer;
|
|
ZeroMemory(&osVer, sizeof osVer);
|
|
osVer.dwOSVersionInfoSize = sizeof osVer;
|
|
|
|
if (!GetVersionEx(&osVer))
|
|
throw scu::OsException(GetLastError());
|
|
|
|
basic_string<unsigned char> sContainerName;
|
|
DWORD dwAcquisitionFlags;
|
|
if ((VER_PLATFORM_WIN32_WINDOWS == osVer.dwPlatformId) ||
|
|
((VER_PLATFORM_WIN32_NT == osVer.dwPlatformId) &&
|
|
(5 > osVer.dwMajorVersion)))
|
|
{
|
|
m_fDeleteOnDestruct = true;
|
|
|
|
// Construct a container name that is unique for this thread
|
|
static char unsigned const szRootContainerName[] = "SLBCSP-";
|
|
sContainerName = szRootContainerName; // prefix for easy debugging
|
|
sContainerName.append(Uuid().AsUString());
|
|
|
|
dwAcquisitionFlags = CRYPT_NEWKEYSET;
|
|
}
|
|
else
|
|
{
|
|
m_fDeleteOnDestruct = false;
|
|
dwAcquisitionFlags = CRYPT_VERIFYCONTEXT;
|
|
}
|
|
|
|
bool fCandidateFound = false;
|
|
for (size_t i = 0;
|
|
(i < (sizeof aszCandidateProviders /
|
|
sizeof *aszCandidateProviders) && !fCandidateFound); i++)
|
|
{
|
|
CString csCntrName(sContainerName.c_str());
|
|
if (CryptAcquireContext(&m_hcryptprov,
|
|
(LPCTSTR)csCntrName,
|
|
aszCandidateProviders[i],
|
|
PROV_RSA_FULL, dwAcquisitionFlags))
|
|
{
|
|
fCandidateFound = true;
|
|
m_szProvider = aszCandidateProviders[i];
|
|
}
|
|
}
|
|
|
|
if (!fCandidateFound)
|
|
throw scu::OsException(GetLastError());
|
|
}
|
|
|
|
AuxContext::AuxContext(HCRYPTPROV hcryptprov,
|
|
bool fTransferOwnership)
|
|
: m_hcryptprov(hcryptprov),
|
|
m_fDeleteOnDestruct(fTransferOwnership),
|
|
m_szProvider()
|
|
{}
|
|
|
|
AuxContext::~AuxContext()
|
|
{
|
|
if (0 != m_hcryptprov)
|
|
{
|
|
if (m_fDeleteOnDestruct)
|
|
{
|
|
char *pszContainerName = 0;
|
|
DWORD dwNameLength;
|
|
if (CryptGetProvParam(m_hcryptprov, PP_CONTAINER, NULL,
|
|
&dwNameLength, 0))
|
|
{
|
|
pszContainerName =
|
|
static_cast<char *>(_alloca(dwNameLength));
|
|
if (!CryptGetProvParam(m_hcryptprov, PP_CONTAINER,
|
|
reinterpret_cast<char unsigned *>(pszContainerName),
|
|
&dwNameLength, 0))
|
|
pszContainerName = 0;
|
|
}
|
|
|
|
if (CryptReleaseContext(m_hcryptprov, 0))
|
|
{
|
|
if (pszContainerName)
|
|
CryptAcquireContext(&m_hcryptprov, (LPCTSTR)pszContainerName,
|
|
m_szProvider, PROV_RSA_FULL,
|
|
CRYPT_DELETEKEYSET);
|
|
}
|
|
}
|
|
else // Just release the context
|
|
{
|
|
CryptReleaseContext(m_hcryptprov, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Operators
|
|
HCRYPTPROV
|
|
AuxContext::operator()() const
|
|
{
|
|
return m_hcryptprov;
|
|
}
|
|
|
|
// Operations
|
|
// Access
|
|
// Predicates
|
|
// Static Variables
|
|
|
|
/////////////////////////// PROTECTED /////////////////////////////////
|
|
|
|
// C'tors/D'tors
|
|
// Operators
|
|
// Operations
|
|
// Access
|
|
// Predicates
|
|
// Static Variables
|
|
|
|
|
|
/////////////////////////// PRIVATE /////////////////////////////////
|
|
|
|
// C'tors/D'tors
|
|
// Operators
|
|
// Operations
|
|
// Access
|
|
// Predicates
|
|
// Static Variables
|
|
|
|
|