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

📄 crdspec_container.cpp

📁 基于SD卡的软实现CSP程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:

		//lResult = hScwGetFileLength(m_pCard->GetProxyHandle(), hCrtFile, &offFileSize);
		//if(FAILED(lResult)) goto cleanup;
        DWORD sizeLow;
		lResult = fp.GetSize(hCrtFile,&offFileSize,&sizeLow);
		if(!lResult)
			goto cleanup;
		
		fileSize = sizeLow == 0?offFileSize:sizeLow;
		pbyPublicKey = new BYTE[fileSize];
		if(!pbyPublicKey) goto cleanup;

		lResult = fp.ReadData(hCrtFile,pbyPublicKey, fileSize, &dwActualBytes);
		if(!lResult || dwActualBytes != fileSize) goto cleanup;

		// Lets Cache Our .crt file. for the next read.
		SetCachedCert(algid,pbyPublicKey,fileSize);
	}

	//If the first byte is a seq. ID, parse it using CAPI2 (if it is unavailable, fail)
	if(ASN1_SEQUENCE_ID == pbyPublicKey[0])
	{
		bRet = GetPublicKeyFromCert(hProv,algid,phKey,pbyPublicKey,fileSize);
	}
	else
	{
		// We have a normal public key.
		if (CryptImportKey(hProv, pbyPublicKey, 
				fileSize, NULL, CRYPT_EXPORTABLE, phKey)) 
		{
			bRet = true;
		}
		else
		{
			printf("import key error:%d",GetLastError());
		}
	}
cleanup:
	if(pbyPublicKey) delete [] pbyPublicKey;
	if(fp.IsValid(hCrtFile)) CloseHandle(hCrtFile);
	if(bLocked) m_pCard->Unlock();
	return bRet;
}


/*
CContainer::GetFileIDOfKey
Purpose:
	Gets the file id of the key with the specified ALG_ID in the
	key container

Params:
	ALG_ID algid: The ALG_ID of the key to find
	WORD*wFileID: The wFileID if it is found

Returns:
	true if the specified key is found
	false otherwise.
*/
bool CContainer::GetKeyInfoOfKey(ALG_ID algid, CCard::KEYINFO *pkiFileID)
{
	assert(!IsBadWritePtr(pkiFileID, SIZE_OF_KEYINFO));

	if(!pkiFileID || !m_pKeyInfo)
		return false;

	//Which type of key are we looking for?
	WORD wOpID = 0;
	switch(algid)
	{
	case AT_SIGNATURE:
	case CALG_RSA_SIGN:
		wOpID = OP_SIGN;
		break;
	case AT_KEYEXCHANGE:
	case CALG_RSA_KEYX:
		wOpID = OP_EXCHANGE | OP_DECRYPT; //The desktop CSP uses OP_DECRYPT
		break;
	default:
		return false;
	}
	int i = 0;
	printf("number of keys:%d\n",m_iNumKeys);
	for (; i<m_iNumKeys; i ++)
	{
		if (m_pKeyInfo[i].wOpID & wOpID)
		{
			printf("Operation is same.\n");
			*pkiFileID = m_pKeyInfo[i];
			return TRUE;
		}
	}
	return FALSE;
}

CCard::KEYINFO *CContainer::NewKey(CCard::KEYINFO *pKeyInfo)
{
	printf("In new key function:\n");
	printf("alg:%d\n",pKeyInfo->wAlgID);
	printf("file:%d\n",pKeyInfo->wFileID);
	printf("size:%d\n",pKeyInfo->wKeyBits);
	printf("operation:%d\n",pKeyInfo->wOpID);
	CCard::KEYINFO *rgKeyInfo = new CCard::KEYINFO[m_iNumKeys + 1];
	if (!rgKeyInfo)
	{
		printf("Eroor to create keyinfo.\n");
		return false;
	}
	if (m_pKeyInfo)
	{
		memcpy(rgKeyInfo,m_pKeyInfo, m_iNumKeys *sizeof(CCard::KEYINFO));
		delete [] m_pKeyInfo;
	}
	m_pKeyInfo = rgKeyInfo;
	m_pKeyInfo[m_iNumKeys] =  *pKeyInfo;
	
	printf("**********************************************\n");
	printf("After new key:\n");
	printf("max key number is:%d\n",m_iNumKeys);
	printf("alg is : %d\n",m_pKeyInfo[m_iNumKeys].wAlgID);
	printf("file is : %d\n",m_pKeyInfo[m_iNumKeys].wFileID);
	printf("size is : %d\n",m_pKeyInfo[m_iNumKeys].wKeyBits);
	printf("operation is : %d\n",m_pKeyInfo[m_iNumKeys].wOpID);
	printf("**********************************************\n");

	m_iNumKeys++;
	return m_pKeyInfo;
}

/*
CContainer::LoadCAPI2Lib
Purpose:
	Loads CAPI2 DLL (crypt32.dll)

Params:
	None.
Returns:
	true if the DLL loads successfully
	false otherwise
*/
bool CContainer::LoadCAPI2Lib()
{
	//Check to see if it's already loaded
	if(m_hCAPI2Lib
		&& m_lpfnCreateCertificateContext
		&& m_lpfnFreeCertificateContext
		&& m_lpfnImportPublicKeyInfoEx )
		return true;

	//If not, load it
	m_hCAPI2Lib = LoadLibrary(WfSC_CAPI2_LIB_NAME);
	if(!m_hCAPI2Lib)
		goto err;
	
	//Get our function ptrs out of it
	m_lpfnCreateCertificateContext = (CERTCREATECERTIFICATECONTEXT)GetProcAddress(m_hCAPI2Lib, WfSC_CERTCREATE_PROC_NAME);
	m_lpfnFreeCertificateContext = (CERTFREECERTIFICATECONTEXT)GetProcAddress(m_hCAPI2Lib, WfSC_CERTFREE_PROC_NAME);
	m_lpfnImportPublicKeyInfoEx = (CRYPTIMPORTPUBLICKEYINFOEX)GetProcAddress(m_hCAPI2Lib, WfSC_CRYPTIMPORTPUBKEYINFOEX_PROC_NAME);
	
	if(!m_lpfnCreateCertificateContext
		|| !m_lpfnFreeCertificateContext
		|| !m_lpfnImportPublicKeyInfoEx)
		goto err;

	return true;

err:
	if(m_hCAPI2Lib) FreeLibrary(m_hCAPI2Lib);
	m_hCAPI2Lib = NULL;
	m_lpfnCreateCertificateContext = NULL;
	m_lpfnImportPublicKeyInfoEx = NULL;
	return false;
}

// Converts an AlgId to a the cache index.
DWORD CContainer::RemapAlgIdToCacheIndex(ALG_ID a) 
{
	if (a == AT_SIGNATURE || a == CALG_RSA_SIGN) a = 0;
	else if (a == AT_KEYEXCHANGE || a == CALG_RSA_KEYX) a = 1;
	else
	{
		assert(0);
		a = 0xDEADBEEF;
	}
	return a;

}

// Get Cached .crt file.
PBYTE CContainer::GetCachedCert(ALG_ID algid, DWORD *len)
{
	// Remap AlgId
	DWORD slot = RemapAlgIdToCacheIndex(algid);
	*len = m_dwCertLen[slot];
	return (m_pCertFile[slot]);

}
// Set Cached .crt file.
bool CContainer::SetCachedCert(ALG_ID algid, BYTE* pbyBuffer, DWORD dwBuffLen)
{
	//1) Remap AlgId.
	DWORD slot = RemapAlgIdToCacheIndex(algid);
	
	// 2) If we had something here , we should free it:
	if (m_pCertFile[slot]) delete [] m_pCertFile[slot];

	// 3) Allocate space.
	m_pCertFile[slot] = new BYTE[dwBuffLen];
	if (!m_pCertFile[slot]) return false;


	// 4)  Copy in the new data.
	memcpy(m_pCertFile[slot], pbyBuffer, dwBuffLen);
	m_dwCertLen[slot] = dwBuffLen;

	return true;
}
/*
CContainer::GetCertificate
Purpose:
	Gets the certificate with the algorithm identifier

Params:
	ALG_ID algid: The algorithm identifier
	BYTE* pbyBuffer: The buffer to copy the certificate to
					 if NULL, dwBuffLen keeps amount of space requird
	DWORD *dwBuffLen: The length of the buffer (in)
					  and the amount of data copied (out)

Returns:
	true if it succeeds, false otherwise
*/
bool CContainer::GetCertificate(ALG_ID algid, BYTE* pbyBuffer, DWORD * pdwBuffLen)
{
	assert(!IsBadReadPtr(pdwBuffLen, sizeof(DWORD)));
	assert(!IsBadWritePtr(pdwBuffLen, sizeof(DWORD)));
	if(!pdwBuffLen)
		return false;
	// Check if we're cached.
	DWORD len;

	PBYTE p = GetCachedCert(algid,&len);
	if (p) // We're already cached.
	{
		// 1) Now check the first byte  to make sure it's a cert.
		if(*p != ASN1_SEQUENCE_ID)
		{
			// It isn't a cert(it's likely a public key). return false
			SetLastError(NTE_FAIL);
			return false;
		}

		//2)  Check we have enough room for the copy.
		if (!pbyBuffer ||  len  <  *pdwBuffLen )
		{
			//Not enough room for the cert, return more data.
			*pdwBuffLen=len;
			SetLastError(ERROR_MORE_DATA);
			if (!pbyBuffer) return true; // If buffer is non - null return true.
			return false;
		}

		// Everything is kosher do the copy.
		ASSERT(*pdwBuffLen >= len );
		*pdwBuffLen=len;
		memcpy(pbyBuffer,p,len );
		return true;
	}

	// We don't have the cert cached.
	if(!m_pCard->Lock()) return false;

	CCard::KEYINFO kiKeyInfo;
	HANDLE hCrtFile = NULL;
	WCHAR szKeyPath[MAX_BUFFER];
	DWORD offFileSize;
	BOOL lResult;
	BOOL bRet = false;
	BYTE byActuallyRead = 0;
//	BYTE byFirstByte;
	DWORD dwError = NTE_FAIL;

	if(!GetKeyInfoOfKey(algid, &kiKeyInfo))
	{
		dwError = NTE_NO_KEY;
		goto cleanup;
	}

	wsprintf(szKeyPath, TEXT("%s/%4.4X%4.4X.crt"), WfSC_DIR_CSP, GetSerNum(), kiKeyInfo.wFileID);

	//lResult = hScwCreateFile(m_pCard->GetProxyHandle(), szKeyPath, NULL, &hCrtFile);
	//if(FAILED(lResult)) goto cleanup;
	hCrtFile = fp.GetFile(szKeyPath);
	if(!fp.IsValid(hCrtFile)) goto cleanup;

	//lResult = hScwGetFileLength(m_pCard->GetProxyHandle(), hCrtFile, &offFileSize);
	//if(FAILED(lResult)) goto cleanup;

	DWORD sizeLow;
	if(!fp.GetSize(hCrtFile,&offFileSize,&sizeLow)) goto cleanup;

	// 1) Make sure first byte is a cert.
	/*lResult = hScwReadFile(m_pCard->GetProxyHandle(), hCrtFile, &byFirstByte, sizeof(byFirstByte), &byActuallyRead);
	if(FAILED(lResult)
		|| byActuallyRead != sizeof(byFirstByte)
		|| byFirstByte != ASN1_SEQUENCE_ID)
		goto cleanup;
		*/
	
	//lResult = hScwSetFilePointer(m_pCard->GetProxyHandle(), hCrtFile, 0, FILE_BEGIN);
	//if(FAILED(lResult)) goto cleanup;

	// 2) Make sure we have enough room to write the cert to the passed in buffer.
	if(!pbyBuffer || *pdwBuffLen < offFileSize)
	{
		*pdwBuffLen = offFileSize;
		dwError = ERROR_MORE_DATA;
		if (!pbyBuffer) 
		{
			bRet =  true; // If buffer is non - null return true.
			SetLastError(ERROR_MORE_DATA);
		}
		goto cleanup;
	}
	
	if(0xFFFFFFFF == SetFilePointer(hCrtFile,0,NULL,FILE_BEGIN)) goto cleanup;
	lResult = fp.ReadData(hCrtFile,pbyBuffer,offFileSize,pdwBuffLen);
	if(!lResult || *pdwBuffLen != offFileSize || pbyBuffer[0] != ASN1_SEQUENCE_ID) goto cleanup;

	// 3) Fill in the user buffer with the cert.
	/*lResult = hScwReadFile32(m_pCard->GetProxyHandle(), hCrtFile, pbyBuffer, offFileSize, pdwBuffLen);
	if(FAILED(lResult)
		|| *pdwBuffLen != offFileSize)
		goto cleanup;*/

	bRet = true;

cleanup:
	if(fp.IsValid(hCrtFile)) CloseHandle(hCrtFile);
	m_pCard->Unlock();
	if( !bRet) SetLastError(dwError);
	return bRet != 0;
}

/*
CContainer::SetCertificate
Purpose:
	Sets the certificate on the key specified by the algid

Params:
	ALG_ID algid: The algorithm id of the key on which to set the cert
	BYTE* pbyBuffer: The certificate data
	DWORD dwBuffLen: The length of the cert data

Returns:
	true if it successfully saves the cert data
	false otherwise
*/
bool CContainer::SetCertificate(ALG_ID algid, BYTE* pbyBuffer, DWORD dwBuffLen)
{
	assert(!IsBadReadPtr(pbyBuffer, dwBuffLen));
	if(!pbyBuffer)
		return false;

	if(!m_pCard->Lock())
		return false;

	BOOL bRet = false;
	BOOL lResult = 0;
	HANDLE hCrtFile = NULL;
	WCHAR szKeyPath[MAX_BUFFER];
	DWORD dwActuallyWritten;
	CCard::KEYINFO kiKeyInfo;

	if(!GetKeyInfoOfKey(algid, &kiKeyInfo))
	{
		SetLastError(NTE_NO_KEY);
		goto cleanup;
	}

	wsprintf(szKeyPath, TEXT("%s/%4.4X%4.4X.crt"), WfSC_DIR_CSP, GetSerNum(), kiKeyInfo.wFileID);

	//lResult = hScwCreateFile(m_pCard->GetProxyHandle(), szKeyPath, WfSC_ACL_DEFAULT,&hCrtFile);
	lResult = fp.FileExist(szKeyPath);

	//If the file already exists, delete it and create a new one
	if(lResult)
	{
		lResult = fp.DelFile(szKeyPath);
		if(!lResult)
			goto cleanup;
		//lResult = hScwCreateFile(m_pCard->GetProxyHandle(), szKeyPath, WfSC_ACL_DEFAULT, &hCrtFile);
	}
	hCrtFile = fp.NewFile(szKeyPath);
	if(!fp.IsValid(hCrtFile))
		goto cleanup;

	lResult = fp.WriteData(hCrtFile, pbyBuffer, dwBuffLen, &dwActuallyWritten);
	if(!lResult || dwActuallyWritten!=dwBuffLen)
		goto cleanup;

	// Now cache the certificate
	SetCachedCert(algid,pbyBuffer,dwActuallyWritten);
	bRet = true;

cleanup:
	if(fp.IsValid(hCrtFile))
		CloseHandle(hCrtFile);
	m_pCard->Unlock();
	return bRet != 0;
}

⌨️ 快捷键说明

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