📄 crdspec_container.cpp
字号:
//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 + -