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); } }
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; }
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)); } }
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; }
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(); }
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); }