16#include "InconsistentDataException.h"
31#include "IllegalStateException.h"
38using namespace calypsonet::terminal::calypso::transaction;
39using namespace keyple::core::util::cpp;
40using namespace keyple::core::util::cpp::exception;
42CalypsoCardUtilAdapter::CalypsoCardUtilAdapter() {}
45 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
46 const std::shared_ptr<AbstractCardCommand> command,
47 const std::shared_ptr<ApduResponseApi> apduResponse,
48 const bool isSessionOpen)
51 updateCalypsoCardReadRecords(calypsoCard,
52 std::dynamic_pointer_cast<CmdCardReadRecords>(command),
56 if (std::dynamic_pointer_cast<CmdCardGetDataFci>(command)) {
57 calypsoCard->initializeWithFci(apduResponse);
58 }
else if (std::dynamic_pointer_cast<CmdCardGetDataFcp>(command)) {
59 updateCalypsoCardWithFcp(calypsoCard, command, apduResponse);
60 }
else if (std::dynamic_pointer_cast<CmdCardGetDataEfList>(command)) {
61 updateCalypsoCardWithEfList(calypsoCard,
62 std::dynamic_pointer_cast<CmdCardGetDataEfList>(command),
64 }
else if (std::dynamic_pointer_cast<CmdCardGetDataTraceabilityInformation>(command)) {
65 updateCalypsoCardWithTraceabilityInformation(
67 std::dynamic_pointer_cast<CmdCardGetDataTraceabilityInformation>(command),
70 throw IllegalStateException(
"Unknown GET DATA command reference.");
73 updateCalypsoCardSearchRecordMultiple(
75 std::dynamic_pointer_cast<CmdCardSearchRecordMultiple>(command),
79 updateCalypsoCardReadRecordMultiple(
81 std::dynamic_pointer_cast<CmdCardReadRecordMultiple>(command),
85 updateCalypsoCardWithFcp(calypsoCard, command, apduResponse);
87 updateCalypsoCardUpdateRecord(
89 std::dynamic_pointer_cast<CmdCardUpdateRecord>(command),
92 updateCalypsoCardWriteRecord(
94 std::dynamic_pointer_cast<CmdCardWriteRecord>(command),
97 updateCalypsoCardAppendRecord(
99 std::dynamic_pointer_cast<CmdCardAppendRecord>(command),
103 updateCalypsoCardIncreaseOrDecrease(
105 std::dynamic_pointer_cast<CmdCardIncreaseOrDecrease>(command),
109 updateCalypsoCardIncreaseOrDecreaseMultiple(
111 std::dynamic_pointer_cast<CmdCardIncreaseOrDecreaseMultiple>(command),
114 updateCalypsoCardOpenSession(
116 std::dynamic_pointer_cast<CmdCardOpenSession>(command),
119 updateCalypsoCardCloseSession(
120 std::dynamic_pointer_cast<CmdCardCloseSession>(command),
123 updateCalypsoCardReadBinary(
125 std::dynamic_pointer_cast<CmdCardReadBinary>(command),
129 updateCalypsoCardUpdateBinary(
131 std::dynamic_pointer_cast<CmdCardUpdateOrWriteBinary>(command),
134 updateCalypsoCardWriteBinary(
136 std::dynamic_pointer_cast<CmdCardUpdateOrWriteBinary>(command),
139 updateCalypsoCardGetChallenge(
141 std::dynamic_pointer_cast<CmdCardGetChallenge>(command),
144 updateCalypsoVerifyPin(
146 std::dynamic_pointer_cast<CmdCardVerifyPin>(command),
149 updateCalypsoCardSvGet(
151 std::dynamic_pointer_cast<CmdCardSvGet>(command),
156 updateCalypsoCardSvOperation(calypsoCard, command, apduResponse);
159 updateCalypsoInvalidateRehabilitate(command, apduResponse);
161 updateCalypsoChangePin(std::dynamic_pointer_cast<CmdCardChangePin>(command), apduResponse);
163 updateCalypsoChangeKey(std::dynamic_pointer_cast<CmdCardChangeKey>(command), apduResponse);
165 throw IllegalStateException(
"Unknown command reference.");
170 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
171 const std::vector<std::shared_ptr<AbstractApduCommand>>& commands,
172 const std::vector<std::shared_ptr<ApduResponseApi>>& apduResponses,
173 const bool isSessionOpen)
180 if (apduResponses.size() > commands.size()) {
181 throw InconsistentDataException(
182 "The number of commands/responses does not match: nb commands = " +
183 std::to_string(commands.size()) +
184 ", nb responses = " +
185 std::to_string(apduResponses.size()));
193 std::vector<std::shared_ptr<AbstractApduCommand>>::const_iterator
194 commandIterator = commands.begin();
195 for (
const auto& apduResponse : apduResponses) {
196 auto command = std::dynamic_pointer_cast<AbstractCardCommand>(*commandIterator++);
204 if (apduResponses.size() < commands.size()) {
205 throw InconsistentDataException(
206 "The number of commands/responses does not match: nb commands = " +
207 std::to_string(commands.size()) +
208 ", nb responses = " +
209 std::to_string(apduResponses.size()));
213void CalypsoCardUtilAdapter::updateCalypsoCardOpenSession(
214 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
215 std::shared_ptr<CmdCardOpenSession> cmdCardOpenSession,
216 const std::shared_ptr<ApduResponseApi> apduResponse)
218 cmdCardOpenSession->setApduResponse(apduResponse).checkStatus();
221 calypsoCard->setDfRatified(cmdCardOpenSession->wasRatified());
223 calypsoCard->setTransactionCounter(cmdCardOpenSession->getTransactionCounterValue());
225 const std::vector<uint8_t>& recordDataRead = cmdCardOpenSession->getRecordDataRead();
227 if (recordDataRead.size() > 0) {
228 calypsoCard->setContent(cmdCardOpenSession->getSfi(),
229 cmdCardOpenSession->getRecordNumber(),
234void CalypsoCardUtilAdapter::updateCalypsoCardCloseSession(
235 std::shared_ptr<CmdCardCloseSession> cmdCardCloseSession,
236 const std::shared_ptr<ApduResponseApi> apduResponse)
238 cmdCardCloseSession->setApduResponse(apduResponse).checkStatus();
241void CalypsoCardUtilAdapter::updateCalypsoCardReadRecords(
242 const std::shared_ptr<CalypsoCardAdapter> calypsoCard,
243 const std::shared_ptr<CmdCardReadRecords> cmdCardReadRecords,
244 const std::shared_ptr<ApduResponseApi> apduResponse,
245 const bool isSessionOpen)
247 cmdCardReadRecords->setApduResponse(apduResponse);
248 checkResponseStatusForStrictAndBestEffortMode(cmdCardReadRecords, isSessionOpen);
251 for (
const auto& entry : cmdCardReadRecords->getRecords()) {
252 calypsoCard->setContent(cmdCardReadRecords->getSfi(), entry.first, entry.second);
256void CalypsoCardUtilAdapter::checkResponseStatusForStrictAndBestEffortMode(
257 const std::shared_ptr<AbstractCardCommand> command,
const bool isSessionOpen)
260 command->checkStatus();
263 command->checkStatus();
264 }
catch (
const CardDataAccessException& e) {
269 if (command->getApduResponse()->getStatusWord() != 0x6A82 &&
270 command->getApduResponse()->getStatusWord() != 0x6A83) {
277void CalypsoCardUtilAdapter::updateCalypsoCardSearchRecordMultiple(
278 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
279 std::shared_ptr<CmdCardSearchRecordMultiple> cmdCardSearchRecordMultiple,
280 const std::shared_ptr<ApduResponseApi> apduResponse,
281 const bool isSessionOpen)
284 cmdCardSearchRecordMultiple->setApduResponse(apduResponse);
285 checkResponseStatusForStrictAndBestEffortMode(cmdCardSearchRecordMultiple, isSessionOpen);
287 if (cmdCardSearchRecordMultiple->getFirstMatchingRecordContent().size() > 0) {
288 calypsoCard->setContent(
289 cmdCardSearchRecordMultiple->getSearchCommandData()->getSfi(),
290 cmdCardSearchRecordMultiple->getSearchCommandData()->getMatchingRecordNumbers()[0],
291 cmdCardSearchRecordMultiple->getFirstMatchingRecordContent());
295void CalypsoCardUtilAdapter::updateCalypsoCardReadRecordMultiple(
296 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
297 std::shared_ptr<CmdCardReadRecordMultiple> cmdCardReadRecordMultiple,
298 const std::shared_ptr<ApduResponseApi> apduResponse,
299 const bool isSessionOpen)
301 cmdCardReadRecordMultiple->setApduResponse(apduResponse);
302 checkResponseStatusForStrictAndBestEffortMode(cmdCardReadRecordMultiple, isSessionOpen);
304 for (
const auto& entry : cmdCardReadRecordMultiple->getResults()) {
305 calypsoCard->setContent(cmdCardReadRecordMultiple->getSfi(),
308 cmdCardReadRecordMultiple->getOffset());
312void CalypsoCardUtilAdapter::updateCalypsoCardReadBinary(
313 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
314 std::shared_ptr<CmdCardReadBinary> cmdCardReadBinary,
315 const std::shared_ptr<ApduResponseApi> apduResponse,
316 const bool isSessionOpen)
319 cmdCardReadBinary->setApduResponse(apduResponse);
320 checkResponseStatusForStrictAndBestEffortMode(cmdCardReadBinary, isSessionOpen);
322 calypsoCard->setContent(cmdCardReadBinary->getSfi(),
324 apduResponse->getDataOut(),
325 cmdCardReadBinary->getOffset());
328void CalypsoCardUtilAdapter::updateCalypsoCardWithFcp(
329 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
330 std::shared_ptr<AbstractCardCommand> command,
331 const std::shared_ptr<ApduResponseApi> apduResponse)
334 command->setApduResponse(apduResponse).checkStatus();
336 std::vector<uint8_t> proprietaryInformation;
338 proprietaryInformation =
339 std::dynamic_pointer_cast<CmdCardSelectFile>(command)->getProprietaryInformation();
341 proprietaryInformation =
342 std::dynamic_pointer_cast<CmdCardGetDataFcp>(command)->getProprietaryInformation();
350 const auto directoryHeader = createDirectoryHeader(proprietaryInformation);
351 calypsoCard->setDirectoryHeader(directoryHeader);
353 auto fileHeader = createFileHeader(proprietaryInformation);
354 calypsoCard->setFileHeader(sfi, fileHeader);
356 throw IllegalStateException(
"Unknown file type: " + std::to_string(fileType));
360void CalypsoCardUtilAdapter::updateCalypsoCardWithEfList(
361 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
362 std::shared_ptr<CmdCardGetDataEfList> command,
363 const std::shared_ptr<ApduResponseApi> apduResponse)
366 command->setApduResponse(apduResponse).checkStatus();
368 const std::map<const std::shared_ptr<FileHeaderAdapter>,
const uint8_t> fileHeaderToSfiMap =
369 command->getEfHeaders();
371 for (
const auto& entry : fileHeaderToSfiMap) {
372 calypsoCard->setFileHeader(entry.second, entry.first);
376void CalypsoCardUtilAdapter::updateCalypsoCardWithTraceabilityInformation(
377 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
378 std::shared_ptr<CmdCardGetDataTraceabilityInformation> command,
379 const std::shared_ptr<ApduResponseApi> apduResponse)
382 command->setApduResponse(apduResponse).checkStatus();
384 calypsoCard->setTraceabilityInformation(apduResponse->getDataOut());
387void CalypsoCardUtilAdapter::updateCalypsoCardUpdateRecord(
388 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
389 std::shared_ptr<CmdCardUpdateRecord> cmdCardUpdateRecord,
390 const std::shared_ptr<ApduResponseApi> apduResponse)
392 cmdCardUpdateRecord->setApduResponse(apduResponse).checkStatus();
394 calypsoCard->setContent(cmdCardUpdateRecord->getSfi(),
395 cmdCardUpdateRecord->getRecordNumber(),
396 cmdCardUpdateRecord->getData());
399void CalypsoCardUtilAdapter::updateCalypsoCardWriteRecord(
400 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
401 std::shared_ptr<CmdCardWriteRecord> cmdCardWriteRecord,
402 const std::shared_ptr<ApduResponseApi> apduResponse)
405 cmdCardWriteRecord->setApduResponse(apduResponse).checkStatus();
407 calypsoCard->fillContent(cmdCardWriteRecord->getSfi(),
408 cmdCardWriteRecord->getRecordNumber(),
409 cmdCardWriteRecord->getData(),
413void CalypsoCardUtilAdapter::updateCalypsoCardUpdateBinary(
414 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
415 std::shared_ptr<CmdCardUpdateOrWriteBinary> cmdCardUpdateBinary,
416 const std::shared_ptr<ApduResponseApi> apduResponse)
418 cmdCardUpdateBinary->setApduResponse(apduResponse).checkStatus();
420 calypsoCard->setContent(cmdCardUpdateBinary->getSfi(),
422 cmdCardUpdateBinary->getData(),
423 cmdCardUpdateBinary->getOffset());
426void CalypsoCardUtilAdapter::updateCalypsoCardWriteBinary(
427 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
428 std::shared_ptr<CmdCardUpdateOrWriteBinary> cmdCardWriteBinary,
429 const std::shared_ptr<ApduResponseApi> apduResponse)
431 cmdCardWriteBinary->setApduResponse(apduResponse).checkStatus();
433 calypsoCard->fillContent(cmdCardWriteBinary->getSfi(),
435 cmdCardWriteBinary->getData(),
436 cmdCardWriteBinary->getOffset());
439void CalypsoCardUtilAdapter::updateCalypsoCardAppendRecord(
440 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
441 std::shared_ptr<CmdCardAppendRecord> cmdCardAppendRecord,
442 const std::shared_ptr<ApduResponseApi> apduResponse)
444 cmdCardAppendRecord->setApduResponse(apduResponse).checkStatus();
446 calypsoCard->addCyclicContent(cmdCardAppendRecord->getSfi(), cmdCardAppendRecord->getData());
449void CalypsoCardUtilAdapter::updateCalypsoCardIncreaseOrDecrease(
450 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
451 std::shared_ptr<CmdCardIncreaseOrDecrease> cmdCardIncreaseOrDecrease,
452 const std::shared_ptr<ApduResponseApi> apduResponse)
455 cmdCardIncreaseOrDecrease->setApduResponse(apduResponse).checkStatus();
457 calypsoCard->setCounter(cmdCardIncreaseOrDecrease->getSfi(),
458 cmdCardIncreaseOrDecrease->getCounterNumber(),
459 apduResponse->getDataOut());
462void CalypsoCardUtilAdapter::updateCalypsoCardIncreaseOrDecreaseMultiple(
463 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
464 std::shared_ptr<CmdCardIncreaseOrDecreaseMultiple> cmdCardIncreaseOrDecreaseMultiple,
465 const std::shared_ptr<ApduResponseApi> apduResponse)
468 cmdCardIncreaseOrDecreaseMultiple->setApduResponse(apduResponse).checkStatus();
470 for (
const auto& entry : cmdCardIncreaseOrDecreaseMultiple->getNewCounterValues()) {
471 calypsoCard->setCounter(cmdCardIncreaseOrDecreaseMultiple->getSfi(),
477void CalypsoCardUtilAdapter::updateCalypsoCardGetChallenge(
478 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
479 std::shared_ptr<CmdCardGetChallenge> cmdCardGetChallenge,
480 const std::shared_ptr<ApduResponseApi> apduResponse)
482 cmdCardGetChallenge->setApduResponse(apduResponse).checkStatus();
483 calypsoCard->setCardChallenge(cmdCardGetChallenge->getCardChallenge());
486void CalypsoCardUtilAdapter::updateCalypsoVerifyPin(
487 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
488 std::shared_ptr<CmdCardVerifyPin> cmdCardVerifyPin,
489 const std::shared_ptr<ApduResponseApi> apduResponse)
491 cmdCardVerifyPin->setApduResponse(apduResponse);
492 calypsoCard->setPinAttemptRemaining(cmdCardVerifyPin->getRemainingAttemptCounter());
495 cmdCardVerifyPin->checkStatus();
496 }
catch (
const CardPinException& ex) {
501 if (!cmdCardVerifyPin->isReadCounterOnly()) {
507void CalypsoCardUtilAdapter::updateCalypsoChangePin(
508 std::shared_ptr<CmdCardChangePin> cmdCardChangePin,
509 const std::shared_ptr<ApduResponseApi> apduResponse)
511 cmdCardChangePin->setApduResponse(apduResponse).checkStatus();
514void CalypsoCardUtilAdapter::updateCalypsoChangeKey(
515 std::shared_ptr<CmdCardChangeKey> cmdCardChangeKey,
516 const std::shared_ptr<ApduResponseApi> apduResponse)
518 cmdCardChangeKey->setApduResponse(apduResponse).checkStatus();
521void CalypsoCardUtilAdapter::updateCalypsoCardSvGet(
522 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
523 std::shared_ptr<CmdCardSvGet> cmdCardSvGet,
524 const std::shared_ptr<ApduResponseApi> apduResponse)
526 cmdCardSvGet->setApduResponse(apduResponse).checkStatus();
528 calypsoCard->setSvData(cmdCardSvGet->getCurrentKVC(),
529 cmdCardSvGet->getSvGetCommandHeader(),
530 cmdCardSvGet->getApduResponse()->getApdu(),
531 cmdCardSvGet->getBalance(),
532 cmdCardSvGet->getTransactionNumber(),
533 cmdCardSvGet->getLoadLog(),
534 cmdCardSvGet->getDebitLog());
537void CalypsoCardUtilAdapter::updateCalypsoCardSvOperation(
538 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
539 std::shared_ptr<AbstractCardCommand> cmdCardSvOperation,
540 const std::shared_ptr<ApduResponseApi> apduResponse)
542 cmdCardSvOperation->setApduResponse(apduResponse).checkStatus();
543 calypsoCard->setSvOperationSignature(cmdCardSvOperation->getApduResponse()->getDataOut());
546void CalypsoCardUtilAdapter::updateCalypsoInvalidateRehabilitate(
547 std::shared_ptr<AbstractCardCommand> cmdCardInvalidateRehabilitate,
548 const std::shared_ptr<ApduResponseApi> apduResponse)
550 cmdCardInvalidateRehabilitate->setApduResponse(apduResponse).checkStatus();
553const std::shared_ptr<DirectoryHeader> CalypsoCardUtilAdapter::createDirectoryHeader(
554 const std::vector<uint8_t>& proprietaryInformation)
557 System::arraycopy(proprietaryInformation,
564 System::arraycopy(proprietaryInformation,
577 .accessConditions(accessConditions)
578 .keyIndexes(keyIndexes)
580 .kvc(WriteAccessLevel::PERSONALIZATION,
582 .kvc(WriteAccessLevel::LOAD,
584 .kvc(WriteAccessLevel::DEBIT,
586 .kif(WriteAccessLevel::PERSONALIZATION,
588 .kif(WriteAccessLevel::LOAD,
590 .kif(WriteAccessLevel::DEBIT,
595ElementaryFile::Type CalypsoCardUtilAdapter::getEfTypeFromCardValue(
const uint8_t efType)
597 ElementaryFile::Type fileType;
600 fileType = ElementaryFile::Type::BINARY;
602 fileType = ElementaryFile::Type::LINEAR;
604 fileType = ElementaryFile::Type::CYCLIC;
606 fileType = ElementaryFile::Type::SIMULATED_COUNTERS;
608 fileType = ElementaryFile::Type::COUNTERS;
610 throw IllegalStateException(
"Unknown EF Type: " + std::to_string(efType));
616const std::shared_ptr<FileHeaderAdapter> CalypsoCardUtilAdapter::createFileHeader(
617 const std::vector<uint8_t>& proprietaryInformation)
619 const ElementaryFile::Type fileType =
625 if (fileType == ElementaryFile::Type::BINARY) {
636 System::arraycopy(proprietaryInformation,
643 System::arraycopy(proprietaryInformation,
651 const uint16_t sharedReference =
660 .recordsNumber(recordsNumber)
661 .recordSize(recordSize)
663 .accessConditions(accessConditions)
664 .keyIndexes(keyIndexes)
666 .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)