28#include "IllegalStateException.h"
35using namespace keyple::core::util::cpp;
36using namespace keyple::core::util::cpp::exception;
38CalypsoCardUtilAdapter::CalypsoCardUtilAdapter() {}
41 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
42 const std::shared_ptr<AbstractCardCommand> command,
43 const std::shared_ptr<ApduResponseApi> apduResponse,
44 const bool isSessionOpen)
47 updateCalypsoCardReadRecords(calypsoCard,
48 std::dynamic_pointer_cast<CmdCardReadRecords>(command),
52 if (std::dynamic_pointer_cast<CmdCardGetDataFci>(command)) {
53 calypsoCard->initializeWithFci(apduResponse);
54 }
else if (std::dynamic_pointer_cast<CmdCardGetDataFcp>(command)) {
55 updateCalypsoCardWithFcp(calypsoCard, command, apduResponse);
56 }
else if (std::dynamic_pointer_cast<CmdCardGetDataEfList>(command)) {
57 updateCalypsoCardWithEfList(calypsoCard,
58 std::dynamic_pointer_cast<CmdCardGetDataEfList>(command),
60 }
else if (std::dynamic_pointer_cast<CmdCardGetDataTraceabilityInformation>(command)) {
61 updateCalypsoCardWithTraceabilityInformation(
63 std::dynamic_pointer_cast<CmdCardGetDataTraceabilityInformation>(command),
66 throw IllegalStateException(
"Unknown GET DATA command reference.");
69 updateCalypsoCardSearchRecordMultiple(
71 std::dynamic_pointer_cast<CmdCardSearchRecordMultiple>(command),
75 updateCalypsoCardReadRecordMultiple(
77 std::dynamic_pointer_cast<CmdCardReadRecordMultiple>(command),
81 updateCalypsoCardWithFcp(calypsoCard, command, apduResponse);
83 updateCalypsoCardUpdateRecord(
85 std::dynamic_pointer_cast<CmdCardUpdateRecord>(command),
88 updateCalypsoCardWriteRecord(
90 std::dynamic_pointer_cast<CmdCardWriteRecord>(command),
93 updateCalypsoCardAppendRecord(
95 std::dynamic_pointer_cast<CmdCardAppendRecord>(command),
99 updateCalypsoCardIncreaseOrDecrease(
101 std::dynamic_pointer_cast<CmdCardIncreaseOrDecrease>(command),
105 updateCalypsoCardIncreaseOrDecreaseMultiple(
107 std::dynamic_pointer_cast<CmdCardIncreaseOrDecreaseMultiple>(command),
110 updateCalypsoCardOpenSession(
112 std::dynamic_pointer_cast<CmdCardOpenSession>(command),
115 updateCalypsoCardCloseSession(
116 std::dynamic_pointer_cast<CmdCardCloseSession>(command),
119 updateCalypsoCardReadBinary(
121 std::dynamic_pointer_cast<CmdCardReadBinary>(command),
125 updateCalypsoCardUpdateBinary(
127 std::dynamic_pointer_cast<CmdCardUpdateOrWriteBinary>(command),
130 updateCalypsoCardWriteBinary(
132 std::dynamic_pointer_cast<CmdCardUpdateOrWriteBinary>(command),
135 updateCalypsoCardGetChallenge(
137 std::dynamic_pointer_cast<CmdCardGetChallenge>(command),
140 updateCalypsoVerifyPin(
142 std::dynamic_pointer_cast<CmdCardVerifyPin>(command),
145 updateCalypsoCardSvGet(
147 std::dynamic_pointer_cast<CmdCardSvGet>(command),
152 updateCalypsoCardSvOperation(calypsoCard, command, apduResponse);
155 updateCalypsoInvalidateRehabilitate(command, apduResponse);
157 updateCalypsoChangePin(std::dynamic_pointer_cast<CmdCardChangePin>(command), apduResponse);
159 updateCalypsoChangeKey(std::dynamic_pointer_cast<CmdCardChangeKey>(command), apduResponse);
161 throw IllegalStateException(
"Unknown command reference.");
166 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
167 const std::vector<std::shared_ptr<AbstractCardCommand>>& commands,
168 const std::vector<std::shared_ptr<ApduResponseApi>>& apduResponses,
169 const bool isSessionOpen)
171 auto responseIterator = apduResponses.begin();
173 if (!commands.empty()) {
174 for (
const auto& command : commands) {
175 const std::shared_ptr<ApduResponseApi> apduResponse = *responseIterator++;
181void CalypsoCardUtilAdapter::updateCalypsoCardOpenSession(
182 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
183 std::shared_ptr<CmdCardOpenSession> cmdCardOpenSession,
184 const std::shared_ptr<ApduResponseApi> apduResponse)
186 cmdCardOpenSession->setApduResponse(apduResponse);
189 calypsoCard->setDfRatified(cmdCardOpenSession->wasRatified());
191 const std::vector<uint8_t>& recordDataRead = cmdCardOpenSession->getRecordDataRead();
193 if (recordDataRead.size() > 0) {
194 calypsoCard->setContent(cmdCardOpenSession->getSfi(),
195 cmdCardOpenSession->getRecordNumber(),
200void CalypsoCardUtilAdapter::updateCalypsoCardCloseSession(
201 std::shared_ptr<CmdCardCloseSession> cmdCardCloseSession,
202 const std::shared_ptr<ApduResponseApi> apduResponse)
204 cmdCardCloseSession->setApduResponse(apduResponse).checkStatus();
207void CalypsoCardUtilAdapter::updateCalypsoCardReadRecords(
208 const std::shared_ptr<CalypsoCardAdapter> calypsoCard,
209 const std::shared_ptr<CmdCardReadRecords> cmdCardReadRecords,
210 const std::shared_ptr<ApduResponseApi> apduResponse,
211 const bool isSessionOpen)
213 cmdCardReadRecords->setApduResponse(apduResponse);
214 checkResponseStatusForStrictAndBestEffortMode(cmdCardReadRecords, isSessionOpen);
217 for (
const auto& entry : cmdCardReadRecords->getRecords()) {
218 calypsoCard->setContent(cmdCardReadRecords->getSfi(), entry.first, entry.second);
222void CalypsoCardUtilAdapter::checkResponseStatusForStrictAndBestEffortMode(
223 const std::shared_ptr<AbstractCardCommand> command,
const bool isSessionOpen)
226 command->checkStatus();
229 command->checkStatus();
230 }
catch (
const CardDataAccessException& e) {
235 if (command->getApduResponse()->getStatusWord() != 0x6A82 &&
236 command->getApduResponse()->getStatusWord() != 0x6A83) {
243void CalypsoCardUtilAdapter::updateCalypsoCardSearchRecordMultiple(
244 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
245 std::shared_ptr<CmdCardSearchRecordMultiple> cmdCardSearchRecordMultiple,
246 const std::shared_ptr<ApduResponseApi> apduResponse,
247 const bool isSessionOpen)
250 cmdCardSearchRecordMultiple->setApduResponse(apduResponse);
251 checkResponseStatusForStrictAndBestEffortMode(cmdCardSearchRecordMultiple, isSessionOpen);
253 if (cmdCardSearchRecordMultiple->getFirstMatchingRecordContent().size() > 0) {
254 calypsoCard->setContent(
255 cmdCardSearchRecordMultiple->getSearchCommandData()->getSfi(),
256 cmdCardSearchRecordMultiple->getSearchCommandData()->getMatchingRecordNumbers()[0],
257 cmdCardSearchRecordMultiple->getFirstMatchingRecordContent());
261void CalypsoCardUtilAdapter::updateCalypsoCardReadRecordMultiple(
262 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
263 std::shared_ptr<CmdCardReadRecordMultiple> cmdCardReadRecordMultiple,
264 const std::shared_ptr<ApduResponseApi> apduResponse,
265 const bool isSessionOpen)
267 cmdCardReadRecordMultiple->setApduResponse(apduResponse);
268 checkResponseStatusForStrictAndBestEffortMode(cmdCardReadRecordMultiple, isSessionOpen);
270 for (
const auto& entry : cmdCardReadRecordMultiple->getResults()) {
271 calypsoCard->setContent(cmdCardReadRecordMultiple->getSfi(),
274 cmdCardReadRecordMultiple->getOffset());
278void CalypsoCardUtilAdapter::updateCalypsoCardReadBinary(
279 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
280 std::shared_ptr<CmdCardReadBinary> cmdCardReadBinary,
281 const std::shared_ptr<ApduResponseApi> apduResponse,
282 const bool isSessionOpen)
285 cmdCardReadBinary->setApduResponse(apduResponse);
286 checkResponseStatusForStrictAndBestEffortMode(cmdCardReadBinary, isSessionOpen);
288 calypsoCard->setContent(cmdCardReadBinary->getSfi(),
290 apduResponse->getDataOut(),
291 cmdCardReadBinary->getOffset());
294void CalypsoCardUtilAdapter::updateCalypsoCardWithFcp(
295 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
296 std::shared_ptr<AbstractCardCommand> command,
297 const std::shared_ptr<ApduResponseApi> apduResponse)
300 command->setApduResponse(apduResponse).checkStatus();
302 std::vector<uint8_t> proprietaryInformation;
304 proprietaryInformation =
305 std::dynamic_pointer_cast<CmdCardSelectFile>(command)->getProprietaryInformation();
307 proprietaryInformation =
308 std::dynamic_pointer_cast<CmdCardGetDataFcp>(command)->getProprietaryInformation();
316 const auto directoryHeader = createDirectoryHeader(proprietaryInformation);
317 calypsoCard->setDirectoryHeader(directoryHeader);
319 auto fileHeader = createFileHeader(proprietaryInformation);
320 calypsoCard->setFileHeader(sfi, fileHeader);
322 throw IllegalStateException(
"Unknown file type: " + std::to_string(fileType));
326void CalypsoCardUtilAdapter::updateCalypsoCardWithEfList(
327 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
328 std::shared_ptr<CmdCardGetDataEfList> command,
329 const std::shared_ptr<ApduResponseApi> apduResponse)
332 command->setApduResponse(apduResponse).checkStatus();
334 const std::map<const std::shared_ptr<FileHeaderAdapter>,
const uint8_t> fileHeaderToSfiMap =
335 command->getEfHeaders();
337 for (
const auto& entry : fileHeaderToSfiMap) {
338 calypsoCard->setFileHeader(entry.second, entry.first);
342void CalypsoCardUtilAdapter::updateCalypsoCardWithTraceabilityInformation(
343 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
344 std::shared_ptr<CmdCardGetDataTraceabilityInformation> command,
345 const std::shared_ptr<ApduResponseApi> apduResponse)
348 command->setApduResponse(apduResponse).checkStatus();
350 calypsoCard->setTraceabilityInformation(apduResponse->getDataOut());
353void CalypsoCardUtilAdapter::updateCalypsoCardUpdateRecord(
354 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
355 std::shared_ptr<CmdCardUpdateRecord> cmdCardUpdateRecord,
356 const std::shared_ptr<ApduResponseApi> apduResponse)
358 cmdCardUpdateRecord->setApduResponse(apduResponse).checkStatus();
360 calypsoCard->setContent(cmdCardUpdateRecord->getSfi(),
361 cmdCardUpdateRecord->getRecordNumber(),
362 cmdCardUpdateRecord->getData());
365void CalypsoCardUtilAdapter::updateCalypsoCardWriteRecord(
366 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
367 std::shared_ptr<CmdCardWriteRecord> cmdCardWriteRecord,
368 const std::shared_ptr<ApduResponseApi> apduResponse)
371 cmdCardWriteRecord->setApduResponse(apduResponse).checkStatus();
373 calypsoCard->fillContent(cmdCardWriteRecord->getSfi(),
374 cmdCardWriteRecord->getRecordNumber(),
375 cmdCardWriteRecord->getData(),
379void CalypsoCardUtilAdapter::updateCalypsoCardUpdateBinary(
380 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
381 std::shared_ptr<CmdCardUpdateOrWriteBinary> cmdCardUpdateBinary,
382 const std::shared_ptr<ApduResponseApi> apduResponse)
384 cmdCardUpdateBinary->setApduResponse(apduResponse).checkStatus();
386 calypsoCard->setContent(cmdCardUpdateBinary->getSfi(),
388 cmdCardUpdateBinary->getData(),
389 cmdCardUpdateBinary->getOffset());
392void CalypsoCardUtilAdapter::updateCalypsoCardWriteBinary(
393 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
394 std::shared_ptr<CmdCardUpdateOrWriteBinary> cmdCardWriteBinary,
395 const std::shared_ptr<ApduResponseApi> apduResponse)
397 cmdCardWriteBinary->setApduResponse(apduResponse).checkStatus();
399 calypsoCard->fillContent(cmdCardWriteBinary->getSfi(),
401 cmdCardWriteBinary->getData(),
402 cmdCardWriteBinary->getOffset());
405void CalypsoCardUtilAdapter::updateCalypsoCardAppendRecord(
406 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
407 std::shared_ptr<CmdCardAppendRecord> cmdCardAppendRecord,
408 const std::shared_ptr<ApduResponseApi> apduResponse)
410 cmdCardAppendRecord->setApduResponse(apduResponse).checkStatus();
412 calypsoCard->addCyclicContent(cmdCardAppendRecord->getSfi(), cmdCardAppendRecord->getData());
415void CalypsoCardUtilAdapter::updateCalypsoCardIncreaseOrDecrease(
416 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
417 std::shared_ptr<CmdCardIncreaseOrDecrease> cmdCardIncreaseOrDecrease,
418 const std::shared_ptr<ApduResponseApi> apduResponse)
421 cmdCardIncreaseOrDecrease->setApduResponse(apduResponse).checkStatus();
423 calypsoCard->setCounter(cmdCardIncreaseOrDecrease->getSfi(),
424 cmdCardIncreaseOrDecrease->getCounterNumber(),
425 apduResponse->getDataOut());
428void CalypsoCardUtilAdapter::updateCalypsoCardIncreaseOrDecreaseMultiple(
429 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
430 std::shared_ptr<CmdCardIncreaseOrDecreaseMultiple> cmdCardIncreaseOrDecreaseMultiple,
431 const std::shared_ptr<ApduResponseApi> apduResponse)
434 cmdCardIncreaseOrDecreaseMultiple->setApduResponse(apduResponse).checkStatus();
436 for (
const auto& entry : cmdCardIncreaseOrDecreaseMultiple->getNewCounterValues()) {
437 calypsoCard->setCounter(cmdCardIncreaseOrDecreaseMultiple->getSfi(),
443void CalypsoCardUtilAdapter::updateCalypsoCardGetChallenge(
444 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
445 std::shared_ptr<CmdCardGetChallenge> cmdCardGetChallenge,
446 const std::shared_ptr<ApduResponseApi> apduResponse)
448 cmdCardGetChallenge->setApduResponse(apduResponse).checkStatus();
449 calypsoCard->setCardChallenge(cmdCardGetChallenge->getCardChallenge());
452void CalypsoCardUtilAdapter::updateCalypsoVerifyPin(
453 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
454 std::shared_ptr<CmdCardVerifyPin> cmdCardVerifyPin,
455 const std::shared_ptr<ApduResponseApi> apduResponse)
457 cmdCardVerifyPin->setApduResponse(apduResponse);
458 calypsoCard->setPinAttemptRemaining(cmdCardVerifyPin->getRemainingAttemptCounter());
461 cmdCardVerifyPin->checkStatus();
462 }
catch (
const CardPinException& ex) {
467 if (!cmdCardVerifyPin->isReadCounterOnly()) {
473void CalypsoCardUtilAdapter::updateCalypsoChangePin(
474 std::shared_ptr<CmdCardChangePin> cmdCardChangePin,
475 const std::shared_ptr<ApduResponseApi> apduResponse)
477 cmdCardChangePin->setApduResponse(apduResponse).checkStatus();
480void CalypsoCardUtilAdapter::updateCalypsoChangeKey(
481 std::shared_ptr<CmdCardChangeKey> cmdCardChangeKey,
482 const std::shared_ptr<ApduResponseApi> apduResponse)
484 cmdCardChangeKey->setApduResponse(apduResponse).checkStatus();
487void CalypsoCardUtilAdapter::updateCalypsoCardSvGet(
488 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
489 std::shared_ptr<CmdCardSvGet> cmdCardSvGet,
490 const std::shared_ptr<ApduResponseApi> apduResponse)
492 cmdCardSvGet->setApduResponse(apduResponse).checkStatus();
494 calypsoCard->setSvData(cmdCardSvGet->getCurrentKVC(),
495 cmdCardSvGet->getSvGetCommandHeader(),
496 cmdCardSvGet->getApduResponse()->getApdu(),
497 cmdCardSvGet->getBalance(),
498 cmdCardSvGet->getTransactionNumber(),
499 cmdCardSvGet->getLoadLog(),
500 cmdCardSvGet->getDebitLog());
503void CalypsoCardUtilAdapter::updateCalypsoCardSvOperation(
504 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
505 std::shared_ptr<AbstractCardCommand> cmdCardSvOperation,
506 const std::shared_ptr<ApduResponseApi> apduResponse)
508 cmdCardSvOperation->setApduResponse(apduResponse).checkStatus();
509 calypsoCard->setSvOperationSignature(cmdCardSvOperation->getApduResponse()->getDataOut());
512void CalypsoCardUtilAdapter::updateCalypsoInvalidateRehabilitate(
513 std::shared_ptr<AbstractCardCommand> cmdCardInvalidateRehabilitate,
514 const std::shared_ptr<ApduResponseApi> apduResponse)
516 cmdCardInvalidateRehabilitate->setApduResponse(apduResponse).checkStatus();
519const std::shared_ptr<DirectoryHeader> CalypsoCardUtilAdapter::createDirectoryHeader(
520 const std::vector<uint8_t>& proprietaryInformation)
523 System::arraycopy(proprietaryInformation,
530 System::arraycopy(proprietaryInformation,
543 .accessConditions(accessConditions)
544 .keyIndexes(keyIndexes)
546 .kvc(WriteAccessLevel::PERSONALIZATION,
548 .kvc(WriteAccessLevel::LOAD,
550 .kvc(WriteAccessLevel::DEBIT,
552 .kif(WriteAccessLevel::PERSONALIZATION,
554 .kif(WriteAccessLevel::LOAD,
556 .kif(WriteAccessLevel::DEBIT,
561ElementaryFile::Type CalypsoCardUtilAdapter::getEfTypeFromCardValue(
const uint8_t efType)
563 ElementaryFile::Type fileType;
566 fileType = ElementaryFile::Type::BINARY;
568 fileType = ElementaryFile::Type::LINEAR;
570 fileType = ElementaryFile::Type::CYCLIC;
572 fileType = ElementaryFile::Type::SIMULATED_COUNTERS;
574 fileType = ElementaryFile::Type::COUNTERS;
576 throw IllegalStateException(
"Unknown EF Type: " + std::to_string(efType));
582const std::shared_ptr<FileHeaderAdapter> CalypsoCardUtilAdapter::createFileHeader(
583 const std::vector<uint8_t>& proprietaryInformation)
585 const ElementaryFile::Type fileType =
591 if (fileType == ElementaryFile::Type::BINARY) {
602 System::arraycopy(proprietaryInformation,
609 System::arraycopy(proprietaryInformation,
617 const uint16_t sharedReference =
626 .recordsNumber(recordsNumber)
627 .recordSize(recordSize)
629 .accessConditions(accessConditions)
630 .keyIndexes(keyIndexes)
632 .sharedReference(sharedReference)
static const CalypsoCardCommand DECREASE
static const CalypsoCardCommand SV_RELOAD
static const CalypsoCardCommand UPDATE_RECORD
static const CalypsoCardCommand INCREASE
static const CalypsoCardCommand SV_DEBIT
static const CalypsoCardCommand READ_RECORD_MULTIPLE
static const CalypsoCardCommand SELECT_FILE
static const CalypsoCardCommand GET_DATA
static const CalypsoCardCommand READ_RECORDS
static const CalypsoCardCommand CHANGE_PIN
static const CalypsoCardCommand READ_BINARY
static const CalypsoCardCommand WRITE_RECORD
static const CalypsoCardCommand CHANGE_KEY
static const CalypsoCardCommand WRITE_BINARY
static const CalypsoCardCommand INVALIDATE
static const CalypsoCardCommand SEARCH_RECORD_MULTIPLE
static const CalypsoCardCommand REHABILITATE
static const CalypsoCardCommand DECREASE_MULTIPLE
static const CalypsoCardCommand SV_GET
static const CalypsoCardCommand GET_CHALLENGE
static const CalypsoCardCommand VERIFY_PIN
static const CalypsoCardCommand SV_UNDEBIT
static const CalypsoCardCommand CLOSE_SESSION
static const CalypsoCardCommand UPDATE_BINARY
static const CalypsoCardCommand OPEN_SESSION
static const CalypsoCardCommand INCREASE_MULTIPLE
static const CalypsoCardCommand APPEND_RECORD
static const int SEL_DF_STATUS_OFFSET
static const int EF_TYPE_CYCLIC
static const int SEL_DATA_REF_OFFSET
static const int SEL_TYPE_OFFSET
static const int SEL_REC_SIZE_OFFSET
static const int SEL_EF_TYPE_OFFSET
static const int FILE_TYPE_EF
static const int SEL_NKEY_LENGTH
static const int SEL_KVCS_OFFSET
static const int FILE_TYPE_MF
static const int SEL_NUM_REC_OFFSET
static const int EF_TYPE_LINEAR
static const int SEL_SFI_OFFSET
static const int EF_TYPE_SIMULATED_COUNTERS
static const int FILE_TYPE_DF
static const int SEL_AC_LENGTH
static const int SEL_LID_OFFSET
static const int SEL_KIFS_OFFSET
static const int SEL_AC_OFFSET
static const int EF_TYPE_BINARY
static const int EF_TYPE_COUNTERS
static const int SEL_NKEY_OFFSET
static void updateCalypsoCard(std::shared_ptr< CalypsoCardAdapter > calypsoCard, const std::shared_ptr< AbstractCardCommand > command, const std::shared_ptr< ApduResponseApi > apduResponse, const bool isSessionOpen)