Esempio n. 1
0
CByteArray CBeidCard::SignInternal(const tPrivKey & key, unsigned long algo,
    const CByteArray & oData, const tPin *pPin)
{
	CAutoLock autolock(this);

	// For V1.7 cards, the Belpic dir has to be selected
	if (m_ucAppletVersion >= 0x17)
		SelectFile(key.csPath);
	else if (m_selectAppletMode == ALW_SELECT_APPLET)
		SelectApplet();

	SetSecurityEnv(key, algo, oData.Size());
 
	// Pretty unique for smart cards: first MSE SET, then verify PIN
    // (needed for the nonrep key/pin, but also usable for the auth key/pin)
    if (pPin != NULL)
    {
        //unsigned long ulRemaining = 0;
        bool bOK = PinCmd(PIN_OP_VERIFY, *pPin, "", "", m_ulRemaining, &key);
        if (!bOK)
			throw CMWEXCEPTION(m_ulRemaining == 0 ? EIDMW_ERR_PIN_BLOCKED : EIDMW_ERR_PIN_BAD);
    }

    // PSO: Compute Digital Signature
    CByteArray oResp = SendAPDU(0x2A, 0x9E, 0x9A, oData);
	unsigned long ulSW12 = getSW12(oResp);
	if (ulSW12 != 0x9000)
		throw CMWEXCEPTION(m_poContext->m_oPCSC.SW12ToErr(ulSW12));

	// Remove SW1-SW2 from the response
	oResp.Chop(2);

	return oResp;
}
Esempio n. 2
0
static long TestPteidCtrl(CReader & oReader, unsigned char ucVersion)
{
	long lErrors = 0;

	printf("\nTesting Ctrl()\n");

	// CTRL_PTEID_GETCARDDATA
	CByteArray oCardInfo = oReader.GetInfo();
	CByteArray oUnsignedCardData = oReader.Ctrl(CTRL_PTEID_GETCARDDATA, CByteArray());
	if (!oCardInfo.Equals(oUnsignedCardData))
		ERR_LOG("ERR: Ctrl(CTRL_PTEID_GETCARDDATA) != GetInfo()\n", lErrors);

	// CTRL_PTEID_GETSIGNEDCARDDATA
	if (ucVersion >= 0x20)
	{
		CByteArray oSignedCardData = oReader.Ctrl(CTRL_PTEID_GETSIGNEDCARDDATA, CByteArray());

		if (oSignedCardData.Size() != oUnsignedCardData.Size() + 128)
			ERR_LOG("ERR: signed and unsigned card data should differ in size by 128 bytes\n", lErrors);

		oSignedCardData.Chop(128);
		if (!oUnsignedCardData.Equals(oSignedCardData))
			ERR_LOG("ERR: start of unsigned card data should be the same as for unsigned card data\n", lErrors);
	}

	// CTRL_PTEID_GETSIGNEDPINSTATUS
	if (ucVersion >= 0x20)
	{
		tPin pin = oReader.GetPin(0);

		CByteArray oData(1);
		oData.Append((unsigned char) pin.ulPinRef);
		CByteArray oSignedPinStatus = oReader.Ctrl(CTRL_PTEID_GETSIGNEDPINSTATUS, oData);

		if (oSignedPinStatus.Size() != 129)
			ERR_LOG("ERR: signed pin status response should be (1 + 128) bytes\n", lErrors);
		else if (oSignedPinStatus.GetByte(0) != oReader.PinStatus(pin))
			ERR_LOG("ERR: signed pin status differs from unsigned PIN status\n", lErrors);
	}

	// CTRL_PTEID_INTERNAL_AUTH
	CByteArray oData(21); // Key ref (1 byte) + challenge(20 bytes)
	oData.Append(0x81);
	for (int i = 0; i < 20; i++)
		oData.Append((unsigned char) rand());
	CByteArray oResp1 = oReader.Ctrl(CTRL_PTEID_INTERNAL_AUTH, oData);
	if (oResp1.Size() != 128)
		ERR_LOG("ERR: Internal Auth. didn't return 128 bytes\n", lErrors);
	CByteArray oResp2 = oReader.Ctrl(CTRL_PTEID_INTERNAL_AUTH, oData);
	if (!oResp1.Equals(oResp2))
		ERR_LOG("ERR: Internal Auth. on the same data returns a different result\n", lErrors);
	oData.SetByte(oData.GetByte(5) + 0x01, 5);
	CByteArray oResp3 = oReader.Ctrl(CTRL_PTEID_INTERNAL_AUTH, oData);
	if (oResp1.Equals(oResp3))
		ERR_LOG("ERR: Internal Auth. on the different data returns the same result\n", lErrors);

	return lErrors;
}
Esempio n. 3
0
static CByteArray ReadInternal(CPCSC *poPCSC, SCARDHANDLE hCard, unsigned long ulOffset, unsigned long ulMaxLen)
{
	unsigned long ulLen = ulMaxLen > 252 ? 252 : ulMaxLen;
	long lretVal = 0;
	unsigned char tucReadDat[5] = {0xFF, 0xB2};
	tucReadDat[2] = (unsigned char)(ulOffset/256);
	tucReadDat[3] = (unsigned char)(ulOffset%256);
	tucReadDat[4] = (unsigned char)(ulLen);
	CByteArray oCmd(tucReadDat, sizeof(tucReadDat));
	CByteArray oData = poPCSC->Transmit(hCard, oCmd, &lretVal);

	oData.Chop(2); // remove SW12

	// If we read enough, or there isn't more to read, return
	if (ulMaxLen == ulLen || oData.Size() < ulLen)
	{
		MWLOG(LEV_INFO, MOD_CAL, L"   Read %d bytes from the SIS card", oData.Size());
		return oData;
	}

	ulLen = oData.Size();
	ulOffset += ulLen;
	ulMaxLen -= ulLen;
	ulLen = ulMaxLen > 252 ? 252 : ulMaxLen;
	tucReadDat[2] = (unsigned char)(ulOffset/256);
	tucReadDat[3] = (unsigned char)(ulOffset%256);
	tucReadDat[4] = (unsigned char)(ulLen);
	oCmd = CByteArray(tucReadDat, sizeof(tucReadDat));
	CByteArray oData2 = poPCSC->Transmit(hCard, oCmd,&lretVal);

	oData2.Chop(2); // remove SW12

	oData.Append(oData2);

	MWLOG(LEV_INFO, MOD_CAL, L"   Read %d bytes from the SIS card", oData.Size());

	return oData;
}
Esempio n. 4
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);
    }
}