Example #1
0
static long TestReadLongFile(CReader & oReader, const std::string & csPath)
{
	long lErrors = 0;

	printf("\nTesting CReader::ReadFile() for long files\n");

	try
	{
		CByteArray oFullData = oReader.ReadFile(csPath, 0, FULL_FILE);

		CByteArray oData1 = oReader.ReadFile(csPath, 0, 252);
		if (oData1.Size() != 252 || memcmp(oFullData.GetBytes(), oData1.GetBytes(), 252) != 0)
			ERR_LOG("ERR: CReader::ReadFile(length != 252) failed\n", lErrors);

		CByteArray oData2 = oReader.ReadFile(csPath, 0, 253);
		if (oData2.Size() != 253 || memcmp(oFullData.GetBytes(), oData2.GetBytes(), 253) != 0)
			ERR_LOG("ERR: CReader::ReadFile(length != 253) failed\n", lErrors);

		CByteArray oData3 = oReader.ReadFile(csPath, 100, 400);
		if (oData3.Size() != 400 || memcmp(oFullData.GetBytes() + 100, oData3.GetBytes(), 400) != 0)
			ERR_LOG("ERR: CReader::ReadFile(offs=100, len = 400) failed\n", lErrors);
	}
	catch(const CMWException &e)
	{
		ERR_LOG("ERR: CReader::ReadFile() threw an MWException\n", lErrors);
		printf("   MWException code: 0x%0x\n", (unsigned)e.GetError());
	}
	catch (...)
	{
		ERR_LOG("ERR: CReader::ReadFile() threw an MWException\n", lErrors);
	}

	return lErrors;
}
Example #2
0
static long TestReadShortFile(CReader & oReader, const std::string & csPath)
{
	long lErrors = 0;

	printf("\nTesting CReader::ReadFile() for short files\n");

	try
	{
		CByteArray oFullData = oReader.ReadFile(csPath, 0, FULL_FILE);

		CByteArray oData1 = oReader.ReadFile(csPath, 2, FULL_FILE);
		if (oData1.Size() + 2 != oFullData.Size() ||
			memcmp(oData1.GetBytes(), oFullData.GetBytes() + 2, oData1.Size()) != 0)
		{
			ERR_LOG("ERR: CReader::ReadFile(offset != 0) failed\n", lErrors);
		}

		CByteArray oData2 = oReader.ReadFile(csPath, 2, oFullData.Size() - 3);
		if (oData2.Size() + 3 != oFullData.Size() ||
			memcmp(oData2.GetBytes(), oFullData.GetBytes() + 2, oData2.Size()) != 0)
		{
			ERR_LOG("ERR: CReader::ReadFile(length != FULL_FILE) failed\n", lErrors);
		}

		CByteArray oData3 = oReader.ReadFile(csPath, 0, oFullData.Size() + 1);
		if (!oData3.Equals(oFullData))
			ERR_LOG("ERR: CReader::ReadFile(length = too long) returned a wrong data\n", lErrors);

		bool bExceptionCaught = false;
		try
		{
			CByteArray oData4 = oReader.ReadFile(csPath, oFullData.Size() + 1, 1);
		}
		catch(CMWException & e) {
			bExceptionCaught = true;
			if ( (unsigned) e.GetError() != EIDMW_ERR_PARAM_RANGE)
			ERR_LOG("ERR: CReader::ReadFile(offset = too long) has thrown the wrong exception\n", lErrors);
		}
		if (!bExceptionCaught)
			ERR_LOG("ERR: CReader::ReadFile(offset = too long) didn't throw an exception\n", lErrors);

		CByteArray oData5 = oReader.ReadFile(csPath, 0, oFullData.Size());
		if (!oData5.Equals(oFullData))
			ERR_LOG("ERR: CReader::ReadFile(length = file size) failed\n", lErrors);
	}
	catch(const CMWException &e)
	{
		ERR_LOG("ERR: CReader::ReadFile() threw an MWException\n", lErrors);
		printf("   MWException code: 0x%0x\n", (unsigned) e.GetError());
	}
	catch (...)
	{
		ERR_LOG("ERR: CReader::ReadFile() threw an Exception\n", lErrors);
	}

	return lErrors;
}
Example #3
0
CByteArray CPkiCard::GetRandom(unsigned long ulLen)
{
	CAutoLock oAutoLock(this);

	if (m_selectAppletMode == ALW_SELECT_APPLET)
	{
		SelectApplet();
	}

	CByteArray oRandom(ulLen);

try_again:
    // Use a Get Challenge command to gather 8 bytes with each loop
    for (unsigned long i = 0; i < ulLen; i += 20)
    {
        unsigned char ucLen = (unsigned char) (ulLen - i > 20 ? 20 : ulLen - i);

        // Get challenge command
        CByteArray oResp = SendAPDU(0x84, 0x00, 0x00, (unsigned char) ucLen);
		if (ShouldSelectApplet(0x84, getSW12(oResp)))
		{
			// First try to select 
			if (SelectApplet())
			{
				m_selectAppletMode = ALW_SELECT_APPLET;
				goto try_again;
			}
		}
		getSW12(oResp, 0x9000);

		oRandom.Append(oResp.GetBytes(), oResp.Size() - 2);
    }

    return oRandom;
}
Example #4
0
/**
 * This is something you typically do just once, unless you
 * want to check if new readers were inserted/removed.
 * Note: PKCS#11 assumes that the number of readers never
 * change, so you have to call this function only in
 * C_GetSlotList().
 */
	CReadersInfo CCardLayer::ListReaders()
	{
		CReadersInfo theReadersInfo;
		CByteArray oReaders;

		// Do an SCardEstablishContext() if not done yet
		try
		{
			m_oPCSC.EstablishContext();
			oReaders = m_oPCSC.ListReaders();
		}
		catch(CMWException & e)
		{
			unsigned long err = e.GetError();

			if (err == EIDMW_ERR_NO_READER)
				return theReadersInfo;

			throw;
		}

		theReadersInfo = CReadersInfo(oReaders);

		if (oReaders.Size() != 0)
		{
			m_szDefaultReaderName = (char *) oReaders.GetBytes();
		}

		return theReadersInfo;
	}
Example #5
0
void CPkiCard::WriteUncachedFile(const std::string & csPath,
    unsigned long ulOffset, const CByteArray & oData)
{
    CAutoLock autolock(this);

    tFileInfo fileInfo = SelectFile(csPath, true);

    const unsigned char *pucData = oData.GetBytes();
    unsigned long ulDataLen = oData.Size();
    for (unsigned long i = 0; i < ulDataLen; i += MAX_APDU_WRITE_LEN)
    {
        unsigned long ulLen = ulDataLen - i;
		if (ulLen > MAX_APDU_WRITE_LEN)
            ulLen = MAX_APDU_WRITE_LEN;

        CByteArray oResp = UpdateBinary(ulOffset + i, CByteArray(pucData + i, ulLen));
		unsigned long ulSW12 = getSW12(oResp);
		if (ulSW12 == 0x6982)
			throw CNotAuthenticatedException(
				EIDMW_ERR_NOT_AUTHENTICATED, fileInfo.lWritePINRef);
		else if (ulSW12 != 0x9000)
			throw CMWEXCEPTION(m_poContext->m_oPCSC.SW12ToErr(ulSW12));
    }

	MWLOG(LEV_INFO, MOD_CAL, L"Written file %ls to card", utilStringWiden(csPath).c_str());

}
Example #6
0
BOOL WINAPI
eidmwGetHashParam(
    IN  HCRYPTPROV hProv,      //!< Handle to provider previously obtained through a call to CPAcquireContext
    IN  HCRYPTHASH hHash,      //!< A reference to the hash object for which to set the parameter
    IN  DWORD dwParam,         //!< Parameter to set
    OUT LPBYTE pbData,         //!< A data buffer in which the parameter data will be returned
    IN OUT LPDWORD pcbDataLen, //!< Length of the data to be returned
    IN  DWORD dwFlags)         //!< No flags currently defined
{
	BOOL bReturnVal = FALSE;
	DWORD dwLastError = 0;

	__CSP_TRY__

	MWLOG(LEV_INFO, MOD_CSP, L"CPGetHashParam(hProv = %d) called", hProv);
	MWLOG(LEV_INFO, MOD_CSP, L"  - IN: hHash = %d", hHash);
	MWLOG(LEV_INFO, MOD_CSP, L"  - IN: dwParam = 0x%0x", dwParam);
	MWLOG(LEV_INFO, MOD_CSP, L"  - IN: pbData = %p", pbData);

	CProviderContext *poProvCtx = g_oProviderContextPool.GetProviderContext(hProv);
	CProviderHash *poProvHash = poProvCtx->GetHash(hHash);

	switch(dwParam)
	{
	case HP_ALGID:
		{
		DWORD dwAlgID = (DWORD) poProvHash->GetAlgid();
		bReturnVal = FillProvParam(pbData, pcbDataLen, &dwAlgID, sizeof(DWORD));
		break;
		}
	case HP_HASHSIZE:
		{
		DWORD dwHashSize = (DWORD) poProvHash->GetLengthBytes();
		bReturnVal = FillProvParam(pbData, pcbDataLen, &dwHashSize, sizeof(DWORD));
		break;
		}
	case HP_HASHVAL:
		{
		CByteArray oHashValue = poProvHash->GetHashValue();
		bReturnVal = FillProvParam(pbData, pcbDataLen, oHashValue.GetBytes(), oHashValue.Size());
		break;
		}
	default:
		dwLastError = NTE_BAD_TYPE;
	}

	__STORE_LASTERROR__

	MWLOG(LEV_INFO, MOD_CSP, L" Returning CPGetHashParam(hProv = %d) with code 0x%0x",
		hProv, bReturnVal ? 0 : dwLastError);
	if (bReturnVal)
		MWLOG(LEV_INFO, MOD_CSP, L"   - OUT: *pcbDataLen = %d", *pcbDataLen);

	__CSP_CATCH_SETLASTERROR__

	return (bReturnVal);
}
Example #7
0
void SODParser::ParseSodEncapsulatedContent(const CByteArray & contents){
	ASN1_ITEM           xLev0Item;
	ASN1_ITEM           xLev1Item;
	ASN1_ITEM           xLev2Item;
	ASN1_ITEM           xLev3Item;
	ASN1_ITEM           xLev4Item;

	xLev0Item.p_data = (unsigned char*)contents.GetBytes();
	xLev0Item.l_data = contents.Size();

	if ((asn1_next_item(&xLev0Item, &xLev1Item)!= 0) ||(xLev1Item.tag != ASN_SEQUENCE))
		throw CMWEXCEPTION(EIDMW_SOD_UNEXPECTED_ASN1_TAG);

	if ((xLev1Item.l_data < 2)|| (asn1_next_item(&xLev1Item, &xLev2Item)!= 0) ||(xLev2Item.tag != ASN_INTEGER))
		throw CMWEXCEPTION(EIDMW_SOD_UNEXPECTED_ASN1_TAG);

	if (bin2int(xLev2Item.p_data, xLev2Item.l_data)!=0)
		throw CMWEXCEPTION(EIDMW_SOD_UNEXPECTED_VALUE);

	if ((xLev1Item.l_data < 2)|| (asn1_next_item(&xLev1Item, &xLev2Item)!= 0) ||(xLev2Item.tag != ASN_SEQUENCE))
		throw CMWEXCEPTION(EIDMW_SOD_UNEXPECTED_ASN1_TAG);

	if ((xLev2Item.l_data < 2)|| (asn1_next_item(&xLev2Item, &xLev3Item)!= 0) ||(xLev3Item.tag != ASN_OID))
		throw CMWEXCEPTION(EIDMW_SOD_UNEXPECTED_ASN1_TAG);

	// martinho: not the intended way, but for now it will do just fine.
	if (memcmp(xLev3Item.p_data, OID_SHA256_ALGORITHM, xLev3Item.l_data) != 0)
		throw CMWEXCEPTION(EIDMW_SOD_UNEXPECTED_ALGO_OID);

	if ((xLev2Item.l_data < 2)|| (asn1_next_item(&xLev2Item, &xLev3Item)!= 0) ||(xLev3Item.tag != ASN_NULL))
		throw CMWEXCEPTION(EIDMW_SOD_UNEXPECTED_ASN1_TAG);

	if ((xLev1Item.l_data < 2)|| (asn1_next_item(&xLev1Item, &xLev2Item)!= 0) ||(xLev2Item.tag != ASN_SEQUENCE))
		throw CMWEXCEPTION(EIDMW_SOD_UNEXPECTED_ASN1_TAG);


	attr = new SODAttributes();
	int i=0;
	while(xLev2Item.l_data > 0){

		if ((xLev2Item.l_data < 2)|| (asn1_next_item(&xLev2Item, &xLev3Item)!= 0) ||(xLev3Item.tag != ASN_SEQUENCE))
			throw CMWEXCEPTION(EIDMW_SOD_UNEXPECTED_ASN1_TAG);

		if ((xLev3Item.l_data < 2)|| (asn1_next_item(&xLev3Item, &xLev4Item)!= 0) ||(xLev4Item.tag != ASN_INTEGER))
			throw CMWEXCEPTION(EIDMW_SOD_UNEXPECTED_ASN1_TAG);

		if (bin2int(xLev4Item.p_data, xLev4Item.l_data)!=(i+1))
			throw CMWEXCEPTION(EIDMW_SOD_UNEXPECTED_VALUE);

		if ((xLev3Item.l_data < 2)|| (asn1_next_item(&xLev3Item, &xLev4Item)!= 0) ||(xLev4Item.tag != ASN_OCTET_STRING))
			throw CMWEXCEPTION(EIDMW_SOD_UNEXPECTED_ASN1_TAG);

		attr->hashes[i].Append(xLev4Item.p_data,xLev4Item.l_data);
		i++;
	}
}
bool APL_CryptoFwk::VerifyRoot(const CByteArray &cert, const unsigned char *const *roots)
{
	const unsigned char *const *proot;
	for(proot=roots;*proot!=NULL;proot++)
	{
		if(memcmp(cert.GetBytes(),*proot,cert.Size())==0)
			return true;
	}

	return false;
}
Example #9
0
bool CByteArray::Equals(const CByteArray & oByteArray) const
{
    if (m_bMallocError)
        throw CMWEXCEPTION(EIDMW_ERR_MEMORY);

    if (m_ulSize == 0 && oByteArray.Size() == 0)
        return true;

    return m_ulSize == oByteArray.Size() &&
        memcmp(m_pucData, oByteArray.GetBytes(), m_ulSize) == 0;
}
Example #10
0
CSISCard::CSISCard(
        SCARDHANDLE			hCard, 
        CContext            *poContext,
	    CPinpad             *poPinpad, 
        const CByteArray    &  oData    // is either the first 26 bytes, or the whole 404 bytes
        ) :CCard(hCard, poContext, poPinpad)
{
	if (oData.Size() == 26)
		m_oCardAtr = oData;
	else
	{
	    m_oCardAtr = CByteArray(oData.GetBytes(), 26);
		m_oCardData = oData;
	}
}
Example #11
0
	std::string * CCardLayer::GetDefaultReader()
	{
		std::string * pRet = &m_szDefaultReaderName;

		if (m_szDefaultReaderName.size() == 0)
		{
			CByteArray csReaders = m_oPCSC.ListReaders();
			if (csReaders.Size() != 0)
			{
				m_szDefaultReaderName = (char *)csReaders.GetBytes();
			}
		}

		return pRet;
	}
Example #12
0
BOOL WINAPI
eidmwGenRandom(
    IN  HCRYPTPROV hProv,  //!< Handle to provider previously obtained through a call to CPAcquireContext
    IN  DWORD cbLen,       //!< Number of bytes of random data requested
    OUT LPBYTE pbBuffer)   //!< Buffer to store the random data
{
	BOOL bReturnVal = FALSE;
	DWORD dwLastError = 0;

	__CSP_TRY__

	MWLOG(LEV_INFO, MOD_CSP, L"CPGenRandom(hProv = %d) called", hProv);
	MWLOG(LEV_INFO, MOD_CSP, L"  - IN: cbLen = %d", cbLen);

	CProviderContext *poProvCtx = g_oProviderContextPool.GetProviderContext(hProv);
	std::string csContainerName = poProvCtx->GetContainerName();

	if (csContainerName == "")
	{
		dwLastError = NTE_NO_KEY;
	}
	else
	{
		CAutoMutex oAutoMutex(&g_oCalMutex);

		CReader *poReader = FindCard(poProvCtx);
		if (poReader == NULL)
		{
			dwLastError = NTE_FAIL;
		}
		else
		{
			CByteArray oRandom = poReader->GetRandom(cbLen);
			memcpy(pbBuffer, oRandom.GetBytes(), oRandom.Size());
			bReturnVal = TRUE;
		}
	}

	__STORE_LASTERROR__

	MWLOG(LEV_INFO, MOD_CSP, L" Returning CPGenRandom(hProv = %d) with code 0x%0x",
		hProv, bReturnVal ? 0 : dwLastError);

	__CSP_CATCH_SETLASTERROR__

	return (bReturnVal);
}
Example #13
0
CByteArray CPkiCard::ReadUncachedFile(const std::string & csPath,
    unsigned long ulOffset, unsigned long ulMaxLen)
{
    CByteArray oData(ulMaxLen);

	CAutoLock autolock(this);

    tFileInfo fileInfo = SelectFile(csPath, true);

    // Loop until we've read ulMaxLen bytes or until EOF (End Of File)
    bool bEOF = false;
    for (unsigned long i = 0; i < ulMaxLen && !bEOF; i += MAX_APDU_READ_LEN)
    {
        unsigned long ulLen = ulMaxLen - i <= MAX_APDU_READ_LEN ?
            ulMaxLen - i : MAX_APDU_READ_LEN;

        CByteArray oResp = ReadBinary(ulOffset + i, ulLen);

        unsigned long ulSW12 = getSW12(oResp);
		// If the file is a multiple of the block read size, you will get
		// an SW12 = 6B00 (at least with BE eID) but that OK then..
        if (ulSW12 == 0x9000 || (i != 0 && ulSW12 == 0x6B00))
            oData.Append(oResp.GetBytes(), oResp.Size() - 2);
		else if (ulSW12 == 0x6982) {
			throw CNotAuthenticatedException(
				EIDMW_ERR_NOT_AUTHENTICATED, fileInfo.lReadPINRef);
		}
		else if (ulSW12 == 0x6B00)
			throw CMWEXCEPTION(EIDMW_ERR_PARAM_RANGE);
		else if (ulSW12 == 0x6D00)
			throw CMWEXCEPTION(EIDMW_ERR_NOT_ACTIVATED);
		else
            throw CMWEXCEPTION(m_poContext->m_oPCSC.SW12ToErr(ulSW12));

        // If the driver/reader itself did the 6CXX handling,
        // we assume we're at the EOF
        if (oResp.Size() < MAX_APDU_READ_LEN)
            bEOF = true;
    }

	MWLOG(LEV_INFO, MOD_CAL, L"   Read file %ls (%d bytes) from card",
		utilStringWiden(csPath).c_str(), oData.Size());

    return oData;
}
Example #14
0
static void WriteFile(const std::string & csSerial, const std::string & csPath, const CByteArray &oData)
{
	std::string csFileName;
	if (csSerial != "")
		csFileName += csSerial + "_";
	csFileName += csPath;
#ifdef WIN32
	FILE *f;
	fopen_s(&f,csFileName.c_str(), "wb");
#else
	FILE *f = fopen(csFileName.c_str(), "wb");
#endif
	if (f != NULL)
	{
		fwrite(oData.GetBytes(), 1, oData.Size(), f);
		printf(" - Written %d bytes to %s\n", oData.Size(), csFileName.c_str());
		fclose(f);
	}
	else
		printf(" - ERR: couldn't write file %s\n", csFileName.c_str());
}
Example #15
0
CByteArray CPinpadLib::PinCmd(SCARDHANDLE hCard, unsigned long ulControl,
	CByteArray oCmd, unsigned char ucPintype, unsigned char ucOperation)
{
#if defined WIN32 && defined BEID_OLD_PINPAD
	if (m_oPinpadLibOldBeid.UseOldLib())
		return m_oPinpadLibOldBeid.PinCmd(hCard, ulControl, oCmd, ucPintype, ucOperation);
#endif

	if (m_ppCmd2 == NULL)
		throw CMWEXCEPTION(EIDMW_ERR_UNKNOWN); // shouldn't happen

	unsigned char tucOut[258];
	DWORD dwOutLen = sizeof(tucOut);
	long lRet = m_ppCmd2(hCard, (int) ulControl, oCmd.GetBytes(), oCmd.Size(),
		tucOut, sizeof(tucOut), &dwOutLen,
		ucPintype, ucOperation, 0, NULL);
	if (lRet != SCARD_S_SUCCESS)
		throw CMWEXCEPTION(EIDMW_ERR_PINPAD);

	return CByteArray(tucOut, dwOutLen);
}
Example #16
0
void CHash::Update(const CByteArray & data, unsigned long ulOffset,
		   unsigned long ulLen)
{
	if (!m_bInitialized)
		throw CMWEXCEPTION(EIDMW_ERR_PARAM_BAD);

	if (ulLen != 0)
	{
		const unsigned char *pucData = data.GetBytes() + ulOffset;

		switch (m_Algo)
		{
			case ALGO_MD5:
				md5_process(&m_md1, pucData, ulLen);
				break;
			case ALGO_SHA1:
				sha1_process(&m_md1, pucData, ulLen);
				break;
			case ALGO_MD5_SHA1:
				md5_process(&m_md1, pucData, ulLen);
				sha1_process(&m_md2, pucData, ulLen);
				break;
			case ALGO_SHA256:
				sha256_process(&m_md1, pucData, ulLen);
				break;
			case ALGO_SHA384:
				sha384_process(&m_md1, pucData, ulLen);
				break;
			case ALGO_SHA512:
				sha512_process(&m_md1, pucData, ulLen);
				break;
			case ALGO_RIPEMD160:
				rmd160_process(&m_md1, pucData, ulLen);
				break;
			default:
				throw CMWEXCEPTION(EIDMW_ERR_PARAM_BAD);
		}
	}
}
Example #17
0
CByteArray APL_Certifs::getTLV()
{
	//First we add all the certs in a tlv
	CTLVBuffer tlvNested;

	CByteArray baCount;
	baCount.AppendLong(countAll(true));
	tlvNested.SetTagData(0x00,baCount.GetBytes(),baCount.Size());	//Tag 0x00 contain the number of certificates
	
	unsigned char j=1;
	for(unsigned long i=0;i<countAll(true);i++)
	{
		APL_Certif *cert=getCert(i,true);
		CByteArray baCert=cert->getTLV();
		tlvNested.SetTagData(j++,baCert.GetBytes(),baCert.Size());
	}

	unsigned long ulLen=tlvNested.GetLengthNeeded();
	unsigned char *pucData= new unsigned char[ulLen];
	tlvNested.Extract(pucData,ulLen);
	CByteArray baCerts(pucData,ulLen);

	delete[] pucData;

	//We nest the tlv into the enclosing tlv
	CTLVBuffer tlv;
	tlv.SetTagData(BEID_TLV_TAG_FILE_CERTS,baCerts.GetBytes(),baCerts.Size());

	ulLen=tlv.GetLengthNeeded();
	pucData= new unsigned char[ulLen];
	tlv.Extract(pucData,ulLen);
	CByteArray ba(pucData,ulLen);

	delete[] pucData;
	
	return ba;
}
Example #18
0
BOOL WINAPI
eidmwSignHash(
    IN  HCRYPTPROV hProv,      //!< Handle to provider previously obtained through a call to CPAcquireContext
    IN  HCRYPTHASH hHash,      //!< Handle to the hash object to be signed
    IN  DWORD dwKeySpec,       //!< Key specifier of the key with which to sign
    IN  LPCWSTR szDescription, //!< Discription of the signature (this parameter should no longer be used)
    IN  DWORD dwFlags,         //!<Currently no flags defined, should be 0
    OUT LPBYTE pbSignature,    //!< Pointer to an output buffer that will contain the resulting signature
    IN OUT LPDWORD pcbSigLen)  //!< Length of the resulting signature 
{
	BOOL bReturnVal = FALSE;
	DWORD dwLastError = 0;

	__CSP_TRY__

	MWLOG(LEV_INFO, MOD_CSP, L"CPSignHash(hProv = %d) called", hProv);
	MWLOG(LEV_INFO, MOD_CSP, L"  - IN: hHash = %d", hHash);
	MWLOG(LEV_INFO, MOD_CSP, L"  - IN: dwKeySpec = %d", dwKeySpec);
	MWLOG(LEV_INFO, MOD_CSP, L"  - IN: pbSignature = %p", pbSignature);

	CProviderContext *poProvCtx = g_oProviderContextPool.GetProviderContext(hProv);
	CProviderHash *poProvHash = poProvCtx->GetHash(hHash, false);
	std::string csContainerName = poProvCtx->GetContainerName();

	if (csContainerName == "")
	{
		dwLastError = NTE_NO_KEY;
	}
	else if (poProvHash == NULL)
	{
		dwLastError = NTE_BAD_HASH;
	}
	else
	{
		CAutoMutex oAutoMutex(&g_oCalMutex);

		CReader *poReader = FindCard(poProvCtx);
		if (poReader == NULL)
		{
			dwLastError = NTE_NO_KEY;
		}
		else
		{
			tPrivKey privKey = FindKey(poReader, csContainerName);

			if (pbSignature == NULL)
			{
				*pcbSigLen = privKey.ulKeyLenBytes;
				if (*pcbSigLen == 0)
					*pcbSigLen = 128; // Default, just in case
				bReturnVal = TRUE;
			}
			else
			{
				unsigned long ulSignAlgo = GetSignAlgo(poProvHash->GetAlgid());
				CByteArray oSignature;
				// If the hash has already been calculated (or given via CPSetHashParam())
				// then we present this value. Otherwise we present the hash object itself
				CByteArray & oHashValue = poProvHash->GetHashValue();
				if (oHashValue.Size() == 0)
					oSignature = poReader->Sign(privKey, ulSignAlgo, poProvHash->GetHashObject());
				else
					oSignature = poReader->Sign(privKey, ulSignAlgo, oHashValue);

				bReturnVal = FillProvParam(pbSignature, pcbSigLen,
					oSignature.GetBytes(), oSignature.Size());
				if (bReturnVal)
					ReverseByteOrder(pbSignature, *pcbSigLen);
			}
		}
	}

	__STORE_LASTERROR__

	MWLOG(LEV_INFO, MOD_CSP, L" Returning CPSignHash(hProv = %d) with code 0x%0x",
		hProv, bReturnVal ? 0 : dwLastError);
	if (bReturnVal)
		MWLOG(LEV_INFO, MOD_CSP, L"   - OUT: *pcbSigLen = %d", *pcbSigLen);

	__CSP_CATCH_SETLASTERROR__

	return (bReturnVal);
}
Example #19
0
void CByteArray::Append(const CByteArray & oByteArray)
{
    Append(oByteArray.GetBytes(), oByteArray.Size());
}
Example #20
0
//copy object into new object
CByteArray::CByteArray(const CByteArray & oByteArray)
{
    MakeArray(oByteArray.GetBytes(), oByteArray.Size());
}
Example #21
0
CByteArray CBeidCard::Ctrl(long ctrl, const CByteArray & oCmdData)
{
	CAutoLock oAutoLock(this);

	switch(ctrl)
    {
    case CTRL_BEID_GETCARDDATA:
        return m_oCardData;
    case CTRL_BEID_GETSIGNEDCARDDATA:
		if (m_ucAppletVersion < 0x17)
			throw CMWEXCEPTION(EIDMW_ERR_NOT_SUPPORTED);
		else
		{
			if (m_selectAppletMode == ALW_SELECT_APPLET)
				SelectApplet();
			m_ucCLA = 0x80;
			CByteArray oRet = SendAPDU(0xE4, 0x02, 0x00, 0x9C);
			m_ucCLA = 0;
			getSW12(oRet, 0x9000);
			oRet.Chop(2);
			return oRet;
		}
    case CTRL_BEID_GETSIGNEDPINSTATUS:
		// oCmdData must contain:
		// - the pin reference (1 byte)
		if (m_ucAppletVersion < 0x17)
			throw CMWEXCEPTION(EIDMW_ERR_NOT_SUPPORTED);
		else
		{
			if (m_selectAppletMode == ALW_SELECT_APPLET)
				SelectApplet();
			unsigned char ucPinRef = oCmdData.GetByte(0);
			m_ucCLA = 0x80;
			CByteArray oRet = SendAPDU(0xEA, 0x02, ucPinRef, 0x81);
			m_ucCLA = 0;
			if (ShouldSelectApplet(0xEA, getSW12(oRet)))
			{
				if (SelectApplet())
				{
					m_selectAppletMode = ALW_SELECT_APPLET;
					m_ucCLA = 0x80;
					CByteArray oRet = SendAPDU(0xEA, 0x02, ucPinRef, 0x81);
					m_ucCLA = 0;
				}
			}
			getSW12(oRet, 0x9000);
			oRet.Chop(2);
			return oRet;
		}
	case CTRL_BEID_INTERNAL_AUTH:
		// oCmdData must contain:
		// - the key reference (1 byte)
		// - the challenge to be signed (20 bytes)
		if (oCmdData.Size() != 21)
			throw CMWEXCEPTION(EIDMW_ERR_PARAM_BAD);
		else
		{
			if (m_selectAppletMode == ALW_SELECT_APPLET)
				SelectApplet();
			unsigned char ucKeyRef = oCmdData.GetByte(0);
			CByteArray oData(22);
			oData.Append(0x94);
			oData.Append(0x14);
			oData.Append(oCmdData.GetBytes() + 1, 20);
			CByteArray oRet = SendAPDU(0x88, 0x02, ucKeyRef, oData);
			if (ShouldSelectApplet(0x88, getSW12(oRet)))
			{
				if (SelectApplet())
				{
					m_selectAppletMode = ALW_SELECT_APPLET;
					CByteArray oRet = SendAPDU(0x88, 0x02, ucKeyRef, oData);
				}
			}
			getSW12(oRet, 0x9000);
			oRet.Chop(2);
			return oRet;
		}
    default:
        MWLOG(LEV_WARN, MOD_CAL, L"Ctrl(): Unknown CRTL code %d (0x%0x) specified", ctrl, ctrl);
		throw CMWEXCEPTION(EIDMW_ERR_PARAM_BAD);
    }
}
Example #22
0
static bool VerifySignature(const CByteArray &oData, const CByteArray & oSignature,
	const CByteArray & oCert, unsigned long ulSignAlgo)
{
	if (!bOpensslInitialized)
	{
		OpenSSL_add_all_algorithms();
		bOpensslInitialized = true;
	}

	unsigned long ulCertLen = oCert.Size();
	unsigned char *pucCert = new unsigned char[ulCertLen];
	memcpy(pucCert, oCert.GetBytes(), ulCertLen);
	BIO *pBio = BIO_new_mem_buf(pucCert, ulCertLen);
	X509 *pCert = d2i_X509_bio(pBio, NULL);
	EVP_PKEY *pKey = X509_get_pubkey(pCert);

	EVP_MD_CTX mdCtx;
	const EVP_MD *pEvpMdAlgo = GetOpensslHash(ulSignAlgo);

	int res = 0;
	if (ulSignAlgo == SIGN_ALGO_SHA1_RSA_PSS)
	{
		// Can't use the EVP_xxx() functions for PSS
		CByteArray oHash = CHash().Hash(ALGO_SHA1, oData);
		RSA *rsa = (RSA *) pKey->pkey.rsa;
		unsigned char tucDecrypted[512];
		RSA_public_decrypt(oSignature.Size(), oSignature.GetBytes(), 
			tucDecrypted, rsa, RSA_NO_PADDING);
		res = RSA_verify_PKCS1_PSS(rsa, oHash.GetBytes(),
			pEvpMdAlgo, tucDecrypted, -2);
	}
	else
	{
		EVP_VerifyInit(&mdCtx, pEvpMdAlgo);
		
		EVP_VerifyUpdate(&mdCtx, oData.GetBytes(), oData.Size());

#if (OPENSSL_VERSION_NUMBER > 0x009070ffL)
		res = EVP_VerifyFinal(&mdCtx, oSignature.GetBytes(), oSignature.Size(), pKey);
#else
		unsigned char* signatureBytes = const_cast<unsigned char*> (oSignature.GetBytes());
		res = EVP_VerifyFinal(&mdCtx, signatureBytes, oSignature.Size(), pKey);
#endif
	
	}

	
	X509_free(pCert);
	
	BIO_free(pBio);
	
	free(pucCert);

	// Result res: 1 = signature OK, 0 = bad signature, other = other err
	if (res == 1)
		return true;
	else
	{
		if (res == 0)
			printf("     ERR: verification of algo %s failed\n", SignAlgo2String(ulSignAlgo));
		else
			printf("     ERR: openssl verification of algo %s returned 0x%0x (%d)\n",
				SignAlgo2String(ulSignAlgo), res, res);
		return false;
	}
}