std::vector<unsigned char> ISO7816StorageCardService::readData(std::shared_ptr<Location> location, std::shared_ptr<AccessInfo> /*aiToUse*/, size_t length, CardBehavior /*behaviorFlags*/)
    {
		std::vector<unsigned char> data;
        EXCEPTION_ASSERT_WITH_LOG(location, std::invalid_argument, "location cannot be null.");

        std::shared_ptr<ISO7816Location> icLocation = std::dynamic_pointer_cast<ISO7816Location>(location);

        EXCEPTION_ASSERT_WITH_LOG(icLocation, std::invalid_argument, "location must be a ISO7816Location.");

        if (icLocation->fileid != 0)
        {
            getISO7816Chip()->getISO7816Commands()->selectFile(icLocation->fileid);
        }
        else
        {
            unsigned char defaultdf[16];
            memset(defaultdf, 0x00, sizeof(defaultdf));
            if (memcmp(icLocation->dfname, defaultdf, sizeof(defaultdf)))
            {
                getISO7816Chip()->getISO7816Commands()->selectFile(icLocation->dfname, icLocation->dfnamelen);
            }
        }

        switch (icLocation->fileType)
        {
        case IFT_MASTER:
        case IFT_DIRECTORY:
            if (icLocation->dataObject > 0)
            {
                data = getISO7816Chip()->getISO7816Commands()->getData(length, icLocation->dataObject);
            }
            else
            {
                THROW_EXCEPTION_WITH_LOG(LibLogicalAccessException, "Please specify a data object.");
            }
            break;

        case IFT_TRANSPARENT:
            data = getISO7816Chip()->getISO7816Commands()->readBinary(length, 0);
            break;

        case IFT_LINEAR_FIXED:
        case IFT_LINEAR_VARIABLE:
        case IFT_CYCLIC:
            THROW_EXCEPTION_WITH_LOG(LibLogicalAccessException, "Not implemented yet.");
            break;

        default:
            THROW_EXCEPTION_WITH_LOG(LibLogicalAccessException, "Doesn't know how to read on this file.");
            break;
        }
		return data;
    }
    void MifarePlusProfile::setDefaultKeysAt(std::shared_ptr<Location> location)
    {
        EXCEPTION_ASSERT_WITH_LOG(location, std::invalid_argument, "location cannot be null.");

        std::shared_ptr<MifarePlusLocation> mLocation = std::dynamic_pointer_cast<MifarePlusLocation>(location);
        EXCEPTION_ASSERT_WITH_LOG(mLocation, std::invalid_argument, "location must be a MifarePlusLocation.");

        if (mLocation->sector != -1)
        {
            setDefaultKeysAt(mLocation->sector);
        }
    }
bool STidPRGReaderUnit::format(uint8_t start, uint8_t end,
                               const std::vector<uint8_t> &pwd)
{
    EXCEPTION_ASSERT_WITH_LOG(end - start <= 11, LibLogicalAccessException,
                              "Cannot use "
                              "that many block.");
    EXCEPTION_ASSERT_WITH_LOG(pwd.size() == 4, LibLogicalAccessException,
                              "Password should be 4 bytes.");
    std::vector<uint8_t> cmd = {0x34, start, end, 4};
    cmd.insert(cmd.end(), pwd.begin(), pwd.end());
    auto ret = getDefaultReaderCardAdapter()->sendCommand(cmd);
    return true;
}
    std::vector<unsigned char> IdOnDemandReaderCardAdapter::adaptAnswer(const std::vector<unsigned char>& answer)
    {
        LOG(LogLevel::COMS) << "Processing the received command buffer " << BufferHelper::getHex(answer) << " command size {" << answer.size() << "} {" << BufferHelper::getStdString(answer) << "}...";

        std::vector<unsigned char> ret;
        EXCEPTION_ASSERT_WITH_LOG(answer.size() >= 2, std::invalid_argument, "A valid buffer size must be at least 2 bytes long");

        std::string strcmdbuf = BufferHelper::getStdString(answer);

        EXCEPTION_ASSERT_WITH_LOG(strcmdbuf.find("ERROR ") == std::string::npos, CardException, "ERROR code returned.");
        EXCEPTION_ASSERT_WITH_LOG(strcmdbuf.find("OK ") != std::string::npos, std::invalid_argument, "The command doesn't return OK code.");

        return ret;
    }
bool STidPRGReaderUnit::writePassword(const std::vector<uint8_t> &old,
                                      const std::vector<uint8_t> &new_pass)
{
    EXCEPTION_ASSERT_WITH_LOG(old.size() == 4, LibLogicalAccessException,
                              "Password must be 4 bytes.");
    EXCEPTION_ASSERT_WITH_LOG(new_pass.size() == 4, LibLogicalAccessException,
                              "Password must be 4 bytes.");

    std::vector<uint8_t> cmd = {0x33, 0, 0, 8};
    cmd.insert(cmd.end(), old.begin(), old.end());
    cmd.insert(cmd.end(), new_pass.begin(), new_pass.end());

    auto ret = getDefaultReaderCardAdapter()->sendCommand(cmd);
    return true;
}
    void OmnikeyXX21ReaderUnit::changeReaderKey(std::shared_ptr<ReaderMemoryKeyStorage> keystorage, const std::vector<unsigned char>& key)
    {
        EXCEPTION_ASSERT_WITH_LOG(keystorage, std::invalid_argument, "Key storage must be defined.");
        EXCEPTION_ASSERT_WITH_LOG(key.size() > 0, std::invalid_argument, "key cannot be empty.");

        std::shared_ptr<PCSCReaderCardAdapter> rca = getDefaultPCSCReaderCardAdapter();
        //rca.reset(new OmnikeyHIDiClassReaderCardAdapter());
        //rca->setReaderUnit(shared_from_this());

        //setIsSecureConnectionMode(true);
        //rca->initSecureModeSession(0xFF);
        rca->sendAPDUCommand(0x84, 0x82, (keystorage->getVolatile() ? 0x00 : 0x20), keystorage->getKeySlot(), static_cast<unsigned char>(key.size()), key);
        //rca->closeSecureModeSession();
        //setIsSecureConnectionMode(false);
    }
	boost::shared_ptr<Format> AccessControlCardService::readFormat(boost::shared_ptr<Format> format, boost::shared_ptr<Location> location, boost::shared_ptr<AccessInfo> aiToUse)
	{
		bool ret = false;
		
		EXCEPTION_ASSERT_WITH_LOG(format, std::invalid_argument, "format to read can't be null.");
		EXCEPTION_ASSERT_WITH_LOG(location, std::invalid_argument, "location parameter can't be null.");

		// By default duplicate the format. Other kind of implementation should override this current method.
		boost::shared_ptr<Format> formatret = Format::getByFormatType(format->getType());
		formatret->unSerialize(format->serialize(), "");

		boost::shared_ptr<StorageCardService> storage = boost::dynamic_pointer_cast<StorageCardService>(d_chip->getService(CST_STORAGE));
		if (storage)
		{
			size_t length = (formatret->getDataLength() + 7) / 8;
			if (length > 0)
			{
				unsigned char *formatBuf = new unsigned char[length];
				if (formatBuf != NULL)
				{
					memset(formatBuf, 0x00, length);
					try
					{
						if (!storage->readData(location, aiToUse, formatBuf, length, CB_AUTOSWITCHAREA))
						{				
							THROW_EXCEPTION_WITH_LOG(CardException, EXCEPTION_MSG_READ);
						}
				
						formatret->setLinearData(formatBuf, length);
						ret = true;
					}
					catch(std::exception&)
					{
						delete[] formatBuf;
						throw;
					}
					delete[] formatBuf;
				}
			}
		}

		if (!ret)
		{
			formatret.reset();
		}

		return formatret;
	}
    void PCSCDataTransport::send(const std::vector<unsigned char>& data)
    {
        d_response.clear();

        EXCEPTION_ASSERT_WITH_LOG(getPCSCReaderUnit(), LibLogicalAccessException, "The PCSC reader unit object"
                "is null. We cannot send.");
        if (data.size() > 0)
        {
            unsigned char returnedData[255];
            ULONG ulNoOfDataReceived = sizeof(returnedData);
            LPCSCARD_IO_REQUEST ior = NULL;
            switch (getPCSCReaderUnit()->getActiveProtocol())
            {
            case SCARD_PROTOCOL_T0:
                ior = SCARD_PCI_T0;
                break;

            case SCARD_PROTOCOL_T1:
                ior = SCARD_PCI_T1;
                break;

            case SCARD_PROTOCOL_RAW:
                ior = SCARD_PCI_RAW;
                break;
            }

            LOG(LogLevel::COMS) << "APDU command: " << BufferHelper::getHex(data);

            unsigned int errorFlag = SCardTransmit(getPCSCReaderUnit()->getHandle(), ior, &data[0], static_cast<DWORD>(data.size()), NULL, returnedData, &ulNoOfDataReceived);

            CheckCardError(errorFlag);
            d_response = std::vector<unsigned char>(returnedData, returnedData + ulNoOfDataReceived);
        }
    }
Example #9
0
        void RSACipher::decipher(const std::vector<unsigned char>& src, std::vector<unsigned char>& dest, const AsymmetricKey& key, KeyCompound key_compound)
        {
            const RSAKey& rsakey = static_cast<const RSAKey&>(key);

            int len = 0;
            size_t sumlen = 0;
            size_t blen = RSA_size(rsakey.d_rsa.get());

            size_t c = (src.size() / blen) + 1;

            dest.resize(RSA_size(rsakey.d_rsa.get()) * c);

            for (size_t offset = 0; offset < src.size(); offset += blen)
            {
                if (blen + offset > src.size())
                {
                    blen = src.size() - offset;
                }

                if (key_compound == KC_PUBLIC)
                {
                    len = RSA_public_decrypt(static_cast<int>(blen), &src[offset], &dest[sumlen], rsakey.d_rsa.get(), RSA_PKCS1_PADDING);
                }
                else
                {
                    len = RSA_private_decrypt(static_cast<int>(blen), &src[offset], &dest[sumlen], rsakey.d_rsa.get(), RSA_PKCS1_PADDING);
                }

                EXCEPTION_ASSERT_WITH_LOG(len >= 0, OpenSSLException, "RSA public decrypt failed");

                sumlen += len;
            }

            dest.resize(sumlen);
        }
std::vector<uint8_t> STidPRGReaderUnit::readBlocks(uint8_t start, uint8_t end)
{
    EXCEPTION_ASSERT_WITH_LOG(end - start <= 11, LibLogicalAccessException,
                              "Cannot read "
                              "that many block.");
    auto ret = getDefaultReaderCardAdapter()->sendCommand({0x41, start, end, 0});
    return ret;
}
    unsigned int MifareStorageCardService::readDataHeader(std::shared_ptr<Location> location, std::shared_ptr<AccessInfo> aiToUse, void* data, size_t dataLength)
    {
        if (data == NULL || dataLength == 0)
        {
            return 16;
        }

        EXCEPTION_ASSERT_WITH_LOG(location, std::invalid_argument, "location cannot be null.");

        std::shared_ptr<MifareLocation> mLocation = std::dynamic_pointer_cast<MifareLocation>(location);
        EXCEPTION_ASSERT_WITH_LOG(mLocation, std::invalid_argument, "location must be a MifareLocation.");

        MifareAccessInfo::SectorAccessBits sab;

        if (aiToUse)
        {
            std::shared_ptr<MifareAccessInfo> mAiToUse = std::dynamic_pointer_cast<MifareAccessInfo>(aiToUse);

            EXCEPTION_ASSERT_WITH_LOG(mAiToUse, std::invalid_argument, "aiToUse must be a MifareAccessInfo");

            if (!mAiToUse->keyA->isEmpty())
            {
                getMifareChip()->getMifareProfile()->setKey(mLocation->sector, KT_KEY_A, mAiToUse->keyA);
            }

            if (!mAiToUse->keyB->isEmpty())
            {
                getMifareChip()->getMifareProfile()->setKey(mLocation->sector, KT_KEY_B, mAiToUse->keyB);
            }

            sab = mAiToUse->sab;
        }
        else
        {
            getMifareChip()->getMifareProfile()->setDefaultKeysAt(mLocation->sector);
            sab.setTransportConfiguration();
        }

        if (dataLength >= 16)
        {
            getMifareChip()->getMifareCommands()->changeBlock(sab, mLocation->sector, getMifareChip()->getMifareCommands()->getNbBlocks(mLocation->sector), false);
            return static_cast<unsigned int>(getMifareChip()->getMifareCommands()->readBinary(static_cast<unsigned char>(getMifareChip()->getMifareCommands()->getSectorStartBlock(mLocation->sector) + getMifareChip()->getMifareCommands()->getNbBlocks(mLocation->sector)), 16).size());
        }

        return 0;
    }
	bool ISO7816StorageCardService::erase(boost::shared_ptr<Location> location, boost::shared_ptr<AccessInfo> /*aiToUse*/)
	{
		bool ret = false;

		EXCEPTION_ASSERT_WITH_LOG(location, std::invalid_argument, "location cannot be null.");
		boost::shared_ptr<ISO7816Location> icLocation = boost::dynamic_pointer_cast<ISO7816Location>(location);

		EXCEPTION_ASSERT_WITH_LOG(icLocation, std::invalid_argument, "location must be a ISO7816Location.");

		if (icLocation->fileid != 0)
		{
			getISO7816Chip()->getISO7816Commands()->selectFile(icLocation->fileid);
		}
		else
		{
			unsigned char defaultdf[16];
			memset(defaultdf, 0x00, sizeof(defaultdf));
			if (memcmp(icLocation->dfname, defaultdf, sizeof(defaultdf)))
			{
				getISO7816Chip()->getISO7816Commands()->selectFile(icLocation->dfname, icLocation->dfnamelen);
			}
		}

		switch (icLocation->fileType)
		{		
		case IFT_TRANSPARENT:
			{
				getISO7816Chip()->getISO7816Commands()->eraseBinay(0);
				ret = true;
			}
			break;

		case IFT_LINEAR_FIXED:
		case IFT_LINEAR_VARIABLE:
		case IFT_CYCLIC:
			THROW_EXCEPTION_WITH_LOG(LibLogicalAccessException, "Not implemented yet.");
			break;

		default:
			THROW_EXCEPTION_WITH_LOG(LibLogicalAccessException, "Doesn't know how to write on this file.");
			break;
		}

		return ret;
	}
    void DESFireStorageCardService::erase(std::shared_ptr<Location> location, std::shared_ptr<AccessInfo> aiToUse)
    {
        EXCEPTION_ASSERT_WITH_LOG(location, std::invalid_argument, "location cannot be null.");

        std::shared_ptr<DESFireLocation> dfLocation = std::dynamic_pointer_cast<DESFireLocation>(location);
        std::shared_ptr<DESFireAccessInfo> dfAiToUse = std::dynamic_pointer_cast<DESFireAccessInfo>(aiToUse);

        EXCEPTION_ASSERT_WITH_LOG(dfLocation, std::invalid_argument, "location must be a DESFireLocation.");

        // Format the card if MCK specified.
        if (!dfAiToUse->masterCardKey->isEmpty())
        {
            getDESFireChip()->getDESFireProfile()->setKey(0, 0, dfAiToUse->masterCardKey);
            getDESFireChip()->getDESFireCommands()->selectApplication(0);
            getDESFireChip()->getDESFireCommands()->authenticate(0);
            getDESFireChip()->getDESFireCommands()->erase();
        }
        // Format the application if MAK specified.
        else if (!dfAiToUse->masterApplicationKey->isEmpty())
        {
            getDESFireChip()->getDESFireProfile()->setKey(dfLocation->aid, 0, dfAiToUse->masterApplicationKey);

            getDESFireChip()->getDESFireCommands()->selectApplication(dfLocation->aid);

            std::vector<unsigned char> files = getDESFireChip()->getDESFireCommands()->getFileIDs();
            for (std::vector<unsigned char>::const_iterator file = files.cbegin(); (file != files.cend()); ++file)
            {
                getDESFireChip()->getDESFireCommands()->deleteFile(*file);
            }

            getDESFireChip()->getDESFireCommands()->changeKey(0, std::shared_ptr<DESFireKey>(new DESFireKey(string("00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"))));
        }
        // Otherwise format the file.
        else
        {
            getDESFireChip()->getDESFireCommands()->selectApplication(dfLocation->aid);

            size_t fileLength = getDESFireChip()->getDESFireCommands()->getFileLength(static_cast<unsigned char>(dfLocation->file));
			std::vector<unsigned char> buf(fileLength, 0x00);

            std::shared_ptr<AccessInfo> ai;
            writeData(location, aiToUse, ai, buf, CB_DEFAULT);
        }
    }
    std::vector<unsigned char> DESFireStorageCardService::readData(std::shared_ptr<Location> location, std::shared_ptr<AccessInfo> aiToUse, size_t dataLength, CardBehavior /*behaviorFlags*/)
    {
        EXCEPTION_ASSERT_WITH_LOG(location, std::invalid_argument, "location cannot be null.");

        std::shared_ptr<DESFireLocation> dfLocation = std::dynamic_pointer_cast<DESFireLocation>(location);
        std::shared_ptr<DESFireAccessInfo> dfAiToUse = std::dynamic_pointer_cast<DESFireAccessInfo>(aiToUse);

        EXCEPTION_ASSERT_WITH_LOG(dfLocation, std::invalid_argument, "location must be a DESFireLocation.");
        if (aiToUse)
        {
            EXCEPTION_ASSERT_WITH_LOG(dfAiToUse, std::invalid_argument, "aiToUse must be a DESFireAccessInfo.");
        }
        else
        {
			dfAiToUse = std::dynamic_pointer_cast<DESFireAccessInfo>(getChip()->createAccessInfo());
        }

		getDESFireChip()->getCrypto()->setDefaultKeysAt(dfLocation);

        getDESFireChip()->getDESFireCommands()->selectApplication(dfLocation);

        bool needLoadKey = true;
        EncryptionMode encMode = dfLocation->securityLevel;
		if (encMode == CM_UNKNOWN || encMode == CM_PLAIN)
        {
            encMode = getDESFireChip()->getDESFireCommands()->getEncryptionMode(static_cast<unsigned char>(dfLocation->file), true, &needLoadKey);
        }

        if (needLoadKey)
        {
			if (dfAiToUse->readKey && !dfAiToUse->readKey->isEmpty())
            {
				getDESFireChip()->getCrypto()->setKey(dfLocation->aid, dfAiToUse->readKeyno, dfAiToUse->readKey);
            }
			else if (dfAiToUse->readKeyno == TaskAccessRights::AR_KEY0 && dfAiToUse->masterApplicationKey && !dfAiToUse->masterApplicationKey->isEmpty())
			{
				getDESFireChip()->getCrypto()->setKey(dfLocation->aid, dfAiToUse->readKeyno, dfAiToUse->masterApplicationKey);
			}

            getDESFireChip()->getDESFireCommands()->authenticate(dfAiToUse->readKeyno);
        }
		
        return getDESFireChip()->getDESFireCommands()->readData(dfLocation->file, dfLocation->byte, (int)(dataLength), encMode);
    }
    void MifareUltralightStorageCardService::writeData(std::shared_ptr<Location> location, std::shared_ptr<AccessInfo> /*aiToUse*/, std::shared_ptr<AccessInfo> aiToWrite, const std::vector<unsigned char>& data, CardBehavior behaviorFlags)
    {
        EXCEPTION_ASSERT_WITH_LOG(location, std::invalid_argument, "location cannot be null.");

        std::shared_ptr<MifareUltralightLocation> mLocation = std::dynamic_pointer_cast<MifareUltralightLocation>(location);
        EXCEPTION_ASSERT_WITH_LOG(mLocation, std::invalid_argument, "location must be a MifareUltralightLocation.");
        std::shared_ptr<MifareUltralightAccessInfo> mAi = std::dynamic_pointer_cast<MifareUltralightAccessInfo>(aiToWrite);

        size_t totaldatalen = data.size() + mLocation->byte;
        int nbPages = 0;
        size_t buflen = 0;
        while (buflen < totaldatalen)
        {
            buflen += 4;
            nbPages++;
        }

        if (nbPages >= 1)
        {
            std::vector<unsigned char> dataPages;
            dataPages.resize(buflen, 0x00);
			std::copy(data.begin(), data.end(), dataPages.begin() + mLocation->byte);

            if (behaviorFlags & CB_AUTOSWITCHAREA)
            {
                getMifareUltralightChip()->getMifareUltralightCommands()->writePages(mLocation->page,
                    mLocation->page + nbPages - 1, dataPages);
            }
            else
            {
				getMifareUltralightChip()->getMifareUltralightCommands()->writePage(mLocation->page, dataPages);
            }

            if (mAi && mAi->lockPage)
            {
                for (int i = mLocation->page; i < mLocation->page + nbPages; ++i)
                {
                    getMifareUltralightChip()->getMifareUltralightCommands()->lockPage(i);
                }
            }
        }
    }
    std::vector<unsigned char> RplethDataTransport::receive(long int timeout)
    {
        std::vector<unsigned char> ret, buf;
		std::chrono::steady_clock::time_point const clock_timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(timeout);

		do
        {
            buf.clear();
            if (d_buffer.size() < 5 || (d_buffer.size() >= 4 && d_buffer.size() < (unsigned int)(4 + d_buffer[3] + 1)))
                buf = TcpDataTransport::receive(timeout);

            if (d_buffer.size() < 8192)
            {
                d_buffer.insert(d_buffer.end(), buf.begin(), buf.end());
                buf.clear();
            }
			else
			{
				d_buffer.clear();
				buf.clear();
			}

            if (d_buffer.size() >= 4)
            {
                unsigned int exceptedlen = 4 + d_buffer[3] + 1;
                if (d_buffer.size() >= exceptedlen)
                {
                    buf.clear();
                    buf.insert(buf.begin(), d_buffer.begin(), d_buffer.begin() + exceptedlen);
                    d_buffer.erase(d_buffer.begin(), d_buffer.begin() + exceptedlen);

                    EXCEPTION_ASSERT_WITH_LOG(buf[0] != 0x01, std::invalid_argument, "The supplied answer buffer get the state : Command failure");
                    EXCEPTION_ASSERT_WITH_LOG(buf[0] != 0x02, std::invalid_argument, "The supplied answer buffer get the state : Bad checksum in command");
                    EXCEPTION_ASSERT_WITH_LOG(buf[0] != 0x03, LibLogicalAccessException, "The supplied answer buffer get the state : Timeout");
                    EXCEPTION_ASSERT_WITH_LOG(buf[0] != 0x04, std::invalid_argument, "The supplied answer buffer get the state : Bad size of command");
                    EXCEPTION_ASSERT_WITH_LOG(buf[0] != 0x05, std::invalid_argument, "The supplied answer buffer get the state : Bad device in command");
                    EXCEPTION_ASSERT_WITH_LOG(buf[0] == 0x00, std::invalid_argument, "The supplied answer buffer is corrupted");

                    std::vector<unsigned char> bufnoc = std::vector<unsigned char>(buf.begin(), buf.end() - 1);
                    unsigned char checksum_receive = buf[buf.size() - 1];
                    EXCEPTION_ASSERT_WITH_LOG(calcChecksum(bufnoc) == checksum_receive, std::invalid_argument, "The supplied answer buffer get the state : Bad checksum in answer");

                    ret.insert(ret.begin(), bufnoc.begin() + 4, bufnoc.end());

                    if (ret.size() != 0 && buf[1] == Device::HID && buf[2] == HidCommand::BADGE)
                    {
                        //save the badge
                        if (d_badges.size() <= 10)
                            d_badges.push_back(ret);
                    }

                    break; //We have a correct answer
                }
            }
		} while (ret.size() == 0 && std::chrono::steady_clock::now() < clock_timeout);
        return ret;
    }
    std::vector<unsigned char> GunneboReaderCardAdapter::adaptAnswer(const std::vector<unsigned char>& answer)
    {
        LOG(LogLevel::COMS) << "Processing the received command buffer " << BufferHelper::getHex(answer) << " command size {" << answer.size() << "}...";

        std::shared_ptr<GunneboReaderUnit> ru = std::dynamic_pointer_cast<GunneboReaderUnit>(getDataTransport()->getReaderUnit());

        EXCEPTION_ASSERT_WITH_LOG(answer.size() >= 3, std::invalid_argument, "A valid command buffer size must be at least 3 bytes long");
        EXCEPTION_ASSERT_WITH_LOG(answer[0] == STX, std::invalid_argument, "The supplied command buffer is not valid (bad STX)");
        size_t foolen = 2;
        if (answer[1] == 0x31 && answer[2] == 0x46)
        {
            foolen = 1;
        }
        EXCEPTION_ASSERT_WITH_LOG(answer[answer.size() - foolen] == ETX, std::invalid_argument, "The supplied command buffer is not valid (bad ETX)");

        // Gunnebo ID is like that: [STX - 1 byte][id - x bytes][ETX - 1 byte][checksum - 1 byte]
        // We don't calculate the checksum ! Who cares ?!? :)

        return std::vector<unsigned char>(answer.begin() + 1, answer.end() - 2);
    }
bool STidPRGReaderUnit::login(const std::vector<uint8_t> &password)
{
    EXCEPTION_ASSERT_WITH_LOG(password.size() == 4, LibLogicalAccessException,
                              "Password must be 4 bytes.");

    std::vector<uint8_t> cmd = {0x30, 0, 0, 4};
    cmd.insert(cmd.end(), password.begin(), password.end());

    auto ret = getDefaultReaderCardAdapter()->sendCommand(cmd);
    return true;
}
bool STidPRGReaderUnit::waitInsertion(unsigned int maxwait)
{
    ElapsedTimeCounter etc;
    EXCEPTION_ASSERT_WITH_LOG(getDataTransport(), LibLogicalAccessException, "No data transport.");
    auto stidprgdt =
        std::dynamic_pointer_cast<STidPRGDataTransport>(getDataTransport());
    EXCEPTION_ASSERT_WITH_LOG(stidprgdt, LibLogicalAccessException, "Invalid data transport.");
    stidprgdt->setReceiveTimeout(100);
    select_chip_type();
    do
    {
        if (d_insertedChip)
        {
            return true;
        }
        d_insertedChip = getCurrentChip();
        std::this_thread::sleep_for(std::chrono::milliseconds(200));
    } while (etc.elapsed() < maxwait);
    return !!d_insertedChip;
}
Example #20
0
	void DESFireProfile::setDefaultKeysAt(boost::shared_ptr<Location> location)
	{
		EXCEPTION_ASSERT_WITH_LOG(location, std::invalid_argument, "location cannot be null.");

		boost::shared_ptr<DESFireLocation> dfLocation = boost::dynamic_pointer_cast<DESFireLocation>(location);
		EXCEPTION_ASSERT_WITH_LOG(dfLocation, std::invalid_argument, "location must be a DESFireLocation.");

		// Application (File keys are Application keys)
		if (dfLocation->aid != -1)
		{
			for (unsigned char i = 0; i < 14; ++i)
			{
				setKey(dfLocation->aid, i, getDefaultKey(DF_KEY_DES));
			}
		}
		// Card
		else
		{
			setKey(0, 0, getDefaultKey(DF_KEY_DES));
		}
	}
Example #21
0
	void MifareProfile::setKeyAt(boost::shared_ptr<Location> location, boost::shared_ptr<AccessInfo> AccessInfo)
	{
		EXCEPTION_ASSERT_WITH_LOG(location, std::invalid_argument, "location cannot be null.");
		EXCEPTION_ASSERT_WITH_LOG(AccessInfo, std::invalid_argument, "AccessInfo cannot be null.");

		boost::shared_ptr<MifareLocation> mLocation = boost::dynamic_pointer_cast<MifareLocation>(location);
		boost::shared_ptr<MifareAccessInfo> mAi = boost::dynamic_pointer_cast<MifareAccessInfo>(AccessInfo);

		EXCEPTION_ASSERT_WITH_LOG(mLocation, std::invalid_argument, "location must be a MifareLocation.");
		EXCEPTION_ASSERT_WITH_LOG(mAi, std::invalid_argument, "AccessInfo must be a MifareAccessInfo.");

		if (!mAi->keyA->isEmpty())
		{
			setKey(mLocation->sector, KT_KEY_A, mAi->keyA);
		}

		if (!mAi->keyB->isEmpty())
		{
			setKey(mLocation->sector, KT_KEY_B, mAi->keyB);
		}
	}
	boost::shared_ptr<Chip> DeisterReaderUnit::getChipInAir()
	{
		boost::shared_ptr<Chip> chip;
		std::vector<unsigned char> cmd;
		cmd.push_back(static_cast<unsigned char>(0x0B));

		std::vector<unsigned char> pollBuf = getDefaultDeisterReaderCardAdapter()->sendCommand(cmd);
		if (pollBuf.size() > 0)
		{
			std::vector<unsigned char> tmpId;
			if (pollBuf.size() > 0)
			{
				EXCEPTION_ASSERT_WITH_LOG(pollBuf[0] == 0x00, LibLogicalAccessException, "Bad polling answer, LOC byte");
				EXCEPTION_ASSERT_WITH_LOG(pollBuf[1] == 0x00, LibLogicalAccessException, "Bad polling answer, RST byte");
				EXCEPTION_ASSERT_WITH_LOG(pollBuf[2] == 0x01, LibLogicalAccessException, "Bad polling answer, NOB byte");
				// Only one card type supported at the same time for now
				std::string cardType = getCardTypeFromDeisterType(static_cast<DeisterCardType>(pollBuf[3]));
				EXCEPTION_ASSERT_WITH_LOG(pollBuf[4] == 0x01, LibLogicalAccessException, "Bad polling answer, DT byte");
				EXCEPTION_ASSERT_WITH_LOG(pollBuf[5] == 0x00, LibLogicalAccessException, "Bad polling answer, No byte");
				EXCEPTION_ASSERT_WITH_LOG(pollBuf[6] > 0, LibLogicalAccessException, "Bad polling answer, Size byte must be greater than zero");
				tmpId = std::vector<unsigned char>(pollBuf.begin() + 7, pollBuf.begin() + 7 + pollBuf[6]);
				std::reverse(tmpId.begin(), tmpId.end());
				chip = ReaderUnit::createChip(
					(d_card_type == "UNKNOWN" ? cardType : d_card_type),
					tmpId
				);
			}
		}

		return chip;
	}
    std::vector<unsigned char> TwicStorageCardService::readData(std::shared_ptr<Location> location, std::shared_ptr<AccessInfo> aiToUse, size_t length, CardBehavior behaviorFlags)
    {
		std::vector<unsigned char> result;
        EXCEPTION_ASSERT_WITH_LOG(location, std::invalid_argument, "location cannot be null.");

        std::shared_ptr<ISO7816Location> icISOLocation = std::dynamic_pointer_cast<ISO7816Location>(location);
        std::shared_ptr<TwicLocation> icLocation = std::dynamic_pointer_cast<TwicLocation>(location);

        if (icISOLocation)
        {
            return ISO7816StorageCardService::readData(location, aiToUse, length, behaviorFlags);
        }
        EXCEPTION_ASSERT_WITH_LOG(icLocation, std::invalid_argument, "location must be a TwicLocation or ISO7816Location.");

        getTwicChip()->getTwicCommands()->selectTWICApplication();
        if (icLocation->tag == 0x00)
        {
            result = getTwicChip()->getTwicCommands()->getTWICData(icLocation->dataObject);
        }
        else
        {
            // A tag is specified, the user want to get only the tag's data.
            size_t dataObjectLength = getTwicChip()->getTwicCommands()->getDataObjectLength(icLocation->dataObject, true);
            std::vector<unsigned char> fulldata = getTwicChip()->getTwicCommands()->getTWICData(icLocation->dataObject);

            if (fulldata.size())
            {
                size_t offset = getTwicChip()->getTwicCommands()->getMinimumBytesRepresentation(getTwicChip()->getTwicCommands()->getMaximumDataObjectLength(icLocation->dataObject)) + 1;
                if (offset < dataObjectLength)
                {
					result = std::vector<unsigned char>(256);
					size_t size = 256;
                    getTwicChip()->getTwicCommands()->getTagData(icLocation, &fulldata[offset], dataObjectLength - offset, &result[0], size);
					result.resize(size);
                }
            }
        }
		return result;
    }
	bool SerialPortDataTransport::connect()
	{
		bool ret = false;

		startAutoDetect();

		EXCEPTION_ASSERT_WITH_LOG(d_port, LibLogicalAccessException, "No serial port configured !");
		EXCEPTION_ASSERT_WITH_LOG(d_port->getSerialPort()->deviceName() != "", LibLogicalAccessException, "Serial port name is empty ! Auto-detect failed !");

		if (!d_port->getSerialPort()->isOpen())
		{
			d_port->getSerialPort()->open();
			configure();
			ret = true;
		}
		else
		{
			ret = true;
		}

		return ret;
	}
    std::shared_ptr<MifareKey> MifarePlusSpringCardCommandsSL1::ConvertKey(std::shared_ptr<Key> key)
    {
        std::shared_ptr<MifarePlusKey> keyToConvert = std::dynamic_pointer_cast<MifarePlusKey>(key);

        EXCEPTION_ASSERT_WITH_LOG(keyToConvert, std::invalid_argument, "key must be a MifarePlusKey.");

        std::shared_ptr<MifareKey> keyConverted(new MifareKey());

        if (keyToConvert->getLength() == MIFARE_PLUS_CRYPTO1_KEY_SIZE)
            keyConverted->setData(keyToConvert->getData());

        return (keyConverted);
    }
    void MifareUltralightCCommands::changeKey(std::shared_ptr<AccessInfo> aiToWrite)
    {
        if (aiToWrite)
        {
            std::shared_ptr<MifareUltralightCAccessInfo> mAi = std::dynamic_pointer_cast<MifareUltralightCAccessInfo>(aiToWrite);
            EXCEPTION_ASSERT_WITH_LOG(mAi, std::invalid_argument, "aiToWrite must be a MifareUltralightCAccessInfo.");

            if (mAi->key)
            {
                changeKey(mAi->key);
            }
        }
    }
bool STidPRGReaderUnit::writeBlock(uint8_t start, uint8_t end,
                                   const std::vector<uint8_t> &data)
{
    EXCEPTION_ASSERT_WITH_LOG(end >= start, LibLogicalAccessException,
                              "Invalid block number")
    EXCEPTION_ASSERT_WITH_LOG(end - start <= 8, LibLogicalAccessException,
                              "Cannot write "
                              "that many block.");
    EXCEPTION_ASSERT_WITH_LOG(static_cast<int>(data.size()) == (end - start + 1) * 4,
                              LibLogicalAccessException,
                              "Not enough or too many bytes of data.");


    uint8_t p1 = static_cast<uint8_t>(((end & 0xFF) << 4) | (start & 0xFF));
    std::vector<uint8_t> cmd = {0x42, p1, 0,
                                static_cast<uint8_t>((end - start + 1) * 4)};


    cmd.insert(cmd.end(), data.begin(), data.end());
    auto ret = getDefaultReaderCardAdapter()->sendCommand(cmd);
    return true;
}
Example #28
0
        std::vector<unsigned char> RSAKey::getPEM(bool discard_private_compound, PEMPassphraseCallback callback, void* userdata) const
        {
            std::shared_ptr<BIO> pbio(BIO_new(BIO_s_mem()), BIO_free);

            if (hasPrivateCompound() && (!discard_private_compound))
            {
                EXCEPTION_ASSERT_WITH_LOG(PEM_write_bio_RSAPrivateKey(pbio.get(), d_rsa.get(), NULL, NULL, 0, callback, userdata), OpenSSLException, "Cannot write PEM data");
            }
            else
            {
                EXCEPTION_ASSERT_WITH_LOG(PEM_write_bio_RSA_PUBKEY(pbio.get(), d_rsa.get()), OpenSSLException, "Cannot write PEM data");
            }

            int len = BIO_pending(pbio.get());

            std::vector<unsigned char> buffer(len);

            BIO_read(pbio.get(), buffer.data(), len);
            buffer.resize(len);

            return buffer;
        }
	size_t MifareSTidSTRCommands::readBinaryIndex(unsigned char keyindex, unsigned char blockno, size_t /*len*/, void* buf, size_t buflen)
	{
		INFO_("Read binary index key index {0x%x(%u)} block {0x%x(%u)} [out] buffer len {%d}",
				keyindex, keyindex, blockno, blockno, buflen);

		INFO_SIMPLE_(" => Rescanning card to avoid bad authentication");
		scanMifare();
		INFO_SIMPLE_("Scan done ! Continue to read binary index.");

		std::vector<unsigned char> command;
		command.push_back(static_cast<unsigned char>(d_lastKeyType));
		command.push_back(keyindex);
		command.push_back(blockno);

		std::vector<unsigned char> sbuf = getSTidSTRReaderCardAdapter()->sendCommand(0x00B1, command);

		EXCEPTION_ASSERT_WITH_LOG(sbuf.size() == 16, LibLogicalAccessException, "The read value should always be 16 bytes long");
		EXCEPTION_ASSERT_WITH_LOG(buflen >= sbuf.size(), LibLogicalAccessException, "The buffer is too short to store the result.");

		memcpy(buf, &sbuf[0], sbuf.size());

		return sbuf.size();
	}
Example #30
0
        RSAKey RSAKey::createFromPEMPrivateKey(const std::vector<unsigned char>& data, PEMPassphraseCallback callback, void* userdata)
        {
            std::vector<unsigned char> datacopy = data;

            std::shared_ptr<BIO> pbio(BIO_new_mem_buf(datacopy.data(), (int)datacopy.size()), BIO_free);

            RSA* prsa = PEM_read_bio_RSAPrivateKey(pbio.get(), NULL, callback, userdata);

            EXCEPTION_ASSERT_WITH_LOG(prsa, OpenSSLException, "Unable to parse the RSA public key PEM data");

            std::shared_ptr<RSA> sprsa(prsa, RSA_free);

            return RSAKey(sprsa, true);
        }