⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 context.cpp

📁 基于SD卡的软实现CSP程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
Context.CPP
Each of these functions are effectively the export functions
only with the context parameter checked and is now
implied by the 'this' ptr.
	call crdspec_card.cpp,crdspec_container.cpp to implement functions.
*/

#include "Context.h"
#include "CRDSPEC_Container.h"
#include "assert.h"
#include "PaddingHelp.h"
#include "csp.h"
#include <windows.h>

//Initialization of static member variable
CHandleTable CContext::m_sHT;

/*
CContext::CContext
Purpose: 
	Construct a context object (returned to the caller as a handle)

Params:
	None.

Returns:
	void
*/
CContext::CContext() : m_pCurrentContainer(NULL), m_dwFlags(0)
{
}


/*
CContext::Initialize
Purpose:
	Initializes the context object

Params:
	const WCHAR IN * const pszContainer: Container name
	const DWORD IN dwFlags: Flags on the object
	PVTableProvStruc IN pVTable: vtable

Returns:
	TRUE if it succeeds, FALSE otherwise.
*/
BOOL CContext::Initialize(const WCHAR IN * const pszContainer,const DWORD IN dwFlags, PVTableProvStruc IN pVTable)
{
	//We need a valid container name
	assert(!IsBadReadPtr(pszContainer, 1));

	m_dwFlags = dwFlags;

	//Initialize our helper classes
	if(!m_rsaProv.Initialize((dwFlags & CRYPT_SILENT) == CRYPT_SILENT))
		return FALSE;

	m_ppManager.Initialize(this);

	//Add ourselves to the context hashtable so we can be found
	//on subsequent lookups.
	if(!m_sHT.AddToTable(this))
	{
		SetLastError(NTE_NO_MEMORY);
		return FALSE;
	}

	//We don't support machine contexts
	if((m_dwFlags & CRYPT_MACHINE_KEYSET) == CRYPT_MACHINE_KEYSET)
	{
		SetLastError(NTE_BAD_FLAGS);
		return FALSE;
	}

	//Only initialize the card and build the container list if
	//we're actually going to use it.  We don't if we're doing
	//a CRYPT_VERIFY_CONTEXT

	if((m_dwFlags & CRYPT_VERIFYCONTEXT) == CRYPT_VERIFYCONTEXT)
		return TRUE;
    //TODO
	//Parse the container name
	WCHAR szReaderName[MAX_BUFFER];
	szReaderName[0] = TEXT('\0');
	WCHAR szContainerName[MAX_BUFFER];
	szContainerName[0] = TEXT('\0');

	//See if the format is \\reader\containername
	if(wcsstr(pszContainer, TEXT("\\\\.\\")) == pszContainer)
	{
		const WCHAR* pContNameStart = wcsstr(pszContainer+4, TEXT("\\"));
		//Check to make sure there is a container name.  If there isn't, return.
		if(!pContNameStart)
		{
			SetLastError(ERROR_INVALID_PARAMETER);
			return FALSE;
		}
		//One past the \ before the container name.
		++pContNameStart;

		DWORD dwCharsOfReader = pContNameStart - pszContainer - 5;
		if(dwCharsOfReader > MAX_BUFFER)
		{
			SetLastError(ERROR_INVALID_PARAMETER);
			return FALSE;
		}

		wcsncpy(szContainerName, pContNameStart, MAX_BUFFER);
		wcscpy(szReaderName, pszContainer + 2);
	}
	else
	{
		wcsncpy(szContainerName, pszContainer, MAX_BUFFER);
		szReaderName[MAX_BUFFER - 1] = TEXT('\0');
	}

	//Make sure it's NULL terminated if it cut it off at MAX_BUFFER
	szContainerName[MAX_BUFFER - 1] = TEXT('\0');

	//Initialize the card
	if(!m_crd.Initialize(szReaderName, dwFlags))
		return FALSE;

	//New keyset?
	if((dwFlags & CRYPT_NEWKEYSET) == CRYPT_NEWKEYSET)
	{
		//Create the keyset on the card
		m_pCurrentContainer = m_crd.CreateContainer(szContainerName);
		if(!m_pCurrentContainer)
		{
			SetLastError(NTE_EXISTS);
			return FALSE;
		}
	}

	//Delete keyset?
	else if((dwFlags&CRYPT_DELETEKEYSET) == CRYPT_DELETEKEYSET)
	{
		//Retrieve the container to be deleted
		m_pCurrentContainer = m_crd.GetContainer(szContainerName);
		//If it exists, delete it
		if(m_pCurrentContainer)
		{
			m_pCurrentContainer->Delete();
			delete m_pCurrentContainer;
		}
		else
		{
			SetLastError(NTE_BAD_KEYSET);
			return FALSE;
		}
	}
	//"Normal" usage of the CSP -- use a keyset.
	else
	{
		m_pCurrentContainer = m_crd.GetContainer(szContainerName);
		if(!m_pCurrentContainer)
		{
			SetLastError(NTE_BAD_KEYSET);
			return FALSE;
		}
	}

	//If we made it through all that, it worked.
	return TRUE;
}

/*
CContext::~CContext
Purpose: 
	Destructor of a context object.  Called when CryptReleaseContext is called.

Params:
	None.

Returns:
	void
*/
CContext::~CContext()
{
	m_sHT.RemoveFromTable(this);
}


/*
CContext::VerifyContext
Purpose: 
	Determines if the context pointer passed in is actually a
	valid ptr to a CContext object.

Params:
	CContext* pSpeculativeContext: Ptr to the obj to be verified.

Returns:
	bool : true if it is valid, false otherwise.
*/
bool CContext::VerifyContext(CContext* pSpeculativeContext)
{
	//Ask the static context hashtable if the context is valid.
	return m_sHT.VerifyExistance(pSpeculativeContext);
}


/*
CContext::GetProvParam
Purpose: 
	Effectively CPGetProvParam with the context parameter missing
	The context that this method is being called on is the current
	object.

Params:
	DWORD dwParam: See MSDN
	BYTE* pbData: See MSDN
	DWORD* dwDataLen: See MSDN
	DWORD dwFlags: See MSDN

Returns:
	BOOL : See MSDN
*/
BOOL CContext::GetProvParam(DWORD dwParam, BYTE* pbData, DWORD* pdwDataLen, DWORD dwFlags)
{
	//If we don't know how big the buffer is, fail.
	if(!pdwDataLen)
	{
		SetLastError(ERROR_INVALID_PARAMETER);
		return FALSE;
	}

	//if we don't get a buffer, set the amount of data to 0.
	if(!pbData)
		*pdwDataLen = 0;

	switch(dwParam)
	{
	case PP_CONTAINER:
		return m_ppManager.HandleContainer(pbData, pdwDataLen, dwFlags);
	case PP_ENUMALGS:
		return m_ppManager.HandleEnumAlgs(pbData, pdwDataLen, dwFlags);
	case PP_ENUMALGS_EX:
		return m_ppManager.HandleEnumAlgsEx(pbData, pdwDataLen, dwFlags);
	case PP_ENUMCONTAINERS:
		return m_ppManager.HandleEnumContainers(&m_crd, pbData, pdwDataLen, dwFlags);
	case PP_IMPTYPE:
		return m_ppManager.HandleImpType(pbData, pdwDataLen, dwFlags);
	case PP_NAME:
		return m_ppManager.HandleName(pbData, pdwDataLen, dwFlags);
	case PP_VERSION:
		return m_ppManager.HandleVersion(pbData, pdwDataLen, dwFlags);
	case PP_SIG_KEYSIZE_INC:
		return m_ppManager.HandleSigKeySizeInc(pbData, pdwDataLen, dwFlags);
	case PP_KEYX_KEYSIZE_INC:
		return m_ppManager.HandleKeyXKeySizeInc(pbData, pdwDataLen, dwFlags);
	case PP_KEYSET_SEC_DESCR:
		SetLastError(NTE_BAD_TYPE);
		return FALSE;
	case PP_UNIQUE_CONTAINER:
		return m_ppManager.HandleUniqueContainer(pbData, pdwDataLen, dwFlags);
	case PP_PROVTYPE:
		return m_ppManager.HandleProvType(pbData, pdwDataLen, dwFlags);
	default:
		SetLastError(NTE_BAD_TYPE);
		return FALSE;
	}
}


/*
CContext::SetProvParam
Purpose: 
	Same as CPSetProvParam (See MSDN).  Context parameter missing
	as the context is the current object (this ptr).  We don't
	support this since it only applies to ACLs.

Params:
	DWORD dwParam: See MSDN
	BYTE* pbData: See MSDN
	DWORD dwFlags: See MSDN

Returns:
	BOOL : See MSDN
*/
BOOL CContext::SetProvParam(DWORD dwParam, BYTE* pbData, DWORD dwFlags)
{
	SetLastError(NTE_BAD_TYPE);
	return FALSE;
}


/*
CContext::CreateHash
Purpose: 
	Same as CP* (See MSDN).  Context parameter missing
	as the context is the current object (this ptr).

	We pass this call along to the RSA base provider.

Params:
	ALG_ID Algid: See MSDN
	HCRYPTKEY hCryptKey: See MSDN
	DWORD dwFlags: See MSDN
	HCRYPTHASH* phHash: See MSDN

Returns:
	BOOL : See MSDN
*/
BOOL CContext::CreateHash(ALG_ID Algid, HCRYPTKEY hCryptKey, DWORD dwFlags, HCRYPTHASH* phHash)
{
	return CryptCreateHash(m_rsaProv,Algid, hCryptKey, dwFlags, phHash);
}


/*
CContext::DestroyHash
Purpose: 
	Same as CP* (See MSDN).  Context parameter missing
	as the context is the current object (this ptr).

	We pass this call along to our RSA base provider.

Params:
	HCRYPTHASH hHash: See MSDN

Returns:
	BOOL : See MSDN
*/
BOOL CContext::DestroyHash(HCRYPTHASH hHash)
{
	return CryptDestroyHash(hHash);
}


/*
CContext::GetHashParam
Purpose: 
	Same as CP* (See MSDN).  Context parameter missing
	as the context is the current object (this ptr).

	Note we simply pass this through to our RSA base provider.

Params:
	HCRYPTHASH hHash: See MSDN
	DWORD dwParam: See MSDN
	BYTE* pbData: See MSDN
	DWORD*pdwDataLen: See MSDN
	DWORD dwFlags: See MSDN

Returns:
	BOOL : See MSDN
*/
BOOL CContext::GetHashParam(HCRYPTHASH hHash, DWORD dwParam, BYTE* pbData, DWORD*pdwDataLen, DWORD dwFlags)
{
	return CryptGetHashParam(hHash, dwParam, pbData, pdwDataLen, dwFlags);
}


/*
CContext::HashData
Purpose: 
	Same as CP* (See MSDN).  Context parameter missing
	as the context is the current object (this ptr).

	Note we simply pass this through to our RSA base provider.

Params:
	HCRYPTHASH hHash: See MSDN
	CONST BYTE* pbData: See MSDN
	DWORD dwDatalen: See MSDN
	DWORD dwFlags: See MSDN

Returns:
	BOOL : See MSDN
*/
BOOL CContext::HashData(HCRYPTHASH hHash, CONST BYTE* pbData, DWORD dwDatalen, DWORD dwFlags)
{
	return CryptHashData(hHash, pbData, dwDatalen, dwFlags);
}


/*
CContext::HashSessionKey
Purpose: 
	Same as CP* (See MSDN).  Context parameter missing
	as the context is the current object (this ptr).

	Note we simply pass this through to our RSA base provider.

Params:
	HCRYPTHASH hHash: See MSDN
	HCRYPTKEY hKey: See MSDN
	DWORD dwFlags: See MSDN

Returns:
	BOOL : See MSDN
*/
BOOL CContext::HashSessionKey(HCRYPTHASH hHash, HCRYPTKEY hKey, DWORD dwFlags)
{
	return CryptHashSessionKey(hHash, hKey, dwFlags);
}


/*
CContext::SetHashParam
Purpose: 
	Same as CP* (See MSDN).  Context parameter missing
	as the context is the current object (this ptr).

	Note we simply pass this through to our RSA base provider.

Params:
	HCRYPTHASH hHash: See MSDN
	DWORD dwParam: See MSDN
	BYTE*pbData: See MSDN
	DWORD dwFlags: See MSDN

Returns:
	BOOL : See MSDN
*/
BOOL CContext::SetHashParam(HCRYPTHASH hHash, DWORD dwParam, BYTE*pbData, DWORD dwFlags)
{
	return CryptSetHashParam(hHash,dwParam,pbData,dwFlags);
}


/*
CContext::Encrypt
Purpose: 
	Same as CP* (See MSDN).  Context parameter missing
	as the context is the current object (this ptr).

	Note we simply pass this through to our RSA base provider.

Params:
	HCRYPTKEY hKey: See MSDN
	HCRYPTHASH hHash: See MSDN
	BOOL Final: See MSDN
	DWORD dwFlags: See MSDN
	BYTE* pbData: See MSDN
	DWORD*pdwDataLen: See MSDN
	DWORD dwBufLen: See MSDN

Returns:
	BOOL : See MSDN
*/
BOOL CContext::Encrypt(HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE* pbData, DWORD*pdwDataLen, DWORD dwBufLen)
{
	return CryptEncrypt(hKey, hHash, Final, dwFlags, pbData, pdwDataLen, dwBufLen);
}


/*
CContext::Decrypt
Purpose: 
	Same as CP* (See MSDN).  Context parameter missing
	as the context is the current object (this ptr).

	Note we simply pass this through to our RSA base provider.

Params:
	HCRYPTKEY hKey: See MSDN
	HCRYPTHASH hHash: See MSDN
	BOOL Final: See MSDN
	DWORD dwFlags: See MSDN
	BYTE*pbData: See MSDN
	DWORD*pdwDataLen: See MSDN

Returns:
	BOOL : See MSDN
*/
BOOL CContext::Decrypt(HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE*pbData, DWORD*pdwDataLen)
{
	return CryptDecrypt(hKey, hHash, Final, dwFlags, pbData, pdwDataLen);
}


/*
CContext::SignHash
Purpose: 
	Same as CP* (See MSDN).  Context parameter missing
	as the context is the current object (this ptr).

	This calls through to the card to ask it to sign the hash.

Params:
	HCRYPTHASH hHash: See MSDN
	DWORD dwKeySpec: See MSDN
	LPCWSTR sDescription: See MSDN
	DWORD dwFlags: See MSDN
	BYTE*pbSignature: See MSDN
	DWORD* pdwSigLen: See MSDN

Returns:
	BOOL : See MSDN
*/
BOOL CContext::SignHash(HCRYPTHASH hHash, DWORD dwKeySpec, LPCWSTR sDescription, DWORD dwFlags, BYTE*pbSignature, DWORD* pdwSigLen)
{
	//No keys are in a verify context
	if((m_dwFlags&CRYPT_VERIFYCONTEXT) == CRYPT_VERIFYCONTEXT)
	{
		SetLastError(NTE_NO_KEY);
		return FALSE;
	}

	ALG_ID algidHash;
	DWORD dwBufferLen;
	
	LPBYTE pbyHash = NULL;
	DWORD dwHashLen;
	const BYTE * pbyOID = NULL;
	DWORD dwOIDLen = 0;
	BOOL bRet = FALSE;

	dwBufferLen = sizeof(algidHash);
	if(!CryptGetHashParam(hHash, HP_ALGID, (LPBYTE)&algidHash, &dwBufferLen, 0))
		return FALSE;

	dwBufferLen = sizeof(dwHashLen);
	if(!CryptGetHashParam(hHash, HP_HASHSIZE, (LPBYTE)&dwHashLen, &dwBufferLen, 0))
		return FALSE;

	//Prepend the appropriate OID to the hash.
	//This means that identical hashes will result in different signatures.
	switch(algidHash)
	{
	case CALG_SSL3_SHAMD5:
		dwOIDLen = 0;
		break;
	case CALG_MD2:
		pbyOID = &kbyoidMD2[0];
		dwOIDLen = sizeof(kbyoidMD2);
		break;
	case CALG_MD4:
		pbyOID = &kbyoidMD4[0];
		dwOIDLen = sizeof(kbyoidMD4);
		break;
	case CALG_MD5:
		pbyOID = &kbyoidMD5[0];
		dwOIDLen = sizeof(kbyoidMD5);
		break;
	case CALG_SHA1:
		pbyOID = &kbyoidSHA1[0];
		dwOIDLen = sizeof(kbyoidSHA1);
		break;
	default:
		SetLastError(NTE_BAD_ALGID);
		return FALSE;
	}

	pbyHash = new BYTE[dwHashLen + dwOIDLen];
	if(!pbyHash)
		return FALSE;

	if(pbyOID)
		memcpy(pbyHash, pbyOID, dwOIDLen);

	if(!CryptGetHashParam(hHash, HP_HASHVAL, pbyHash+dwOIDLen, &dwHashLen, 0))
		goto cleanup;

	if(!m_crd.SignHash(m_pCurrentContainer, dwKeySpec, pbyHash, dwHashLen+dwOIDLen, pbSignature, pdwSigLen))
		goto cleanup;

	bRet = TRUE;

cleanup:
	if(pbyHash)
		delete [] pbyHash;

	return bRet;
}


/*
CContext::VerifySignature
Purpose: 
	Same as CP* (See MSDN).  Context parameter missing
	as the context is the current object (this ptr).

	Note we simply pass this through to our RSA base provider.

Params:
	HCRYPTHASH hHash: See MSDN
	CONST BYTE* pbSignature: See MSDN
	DWORD dwSigLen: See MSDN
	HCRYPTKEY hPubKey: See MSDN
	LPCWSTR sDescription: See MSDN
	DWORD dwFlags: See MSDN

Returns:
	BOOL : _
*/
BOOL CContext::VerifySignature(HCRYPTHASH hHash, CONST BYTE* pbSignature, DWORD dwSigLen, HCRYPTKEY hPubKey, LPCWSTR sDescription, DWORD dwFlags)
{
	return CryptVerifySignature(hHash, pbSignature, dwSigLen, hPubKey, (reinterpret_cast<const WCHAR*>(sDescription)), dwFlags);
}


/*
CContext::DeriveKey
Purpose: 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -