Keyple Card Calypso C++ Library 2.2.2
Reference Terminal Reader API for C++
CalypsoCardUtilAdapter.cpp
Go to the documentation of this file.
1/**************************************************************************************************
2 * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ *
3 * *
4 * See the NOTICE file(s) distributed with this work for additional information regarding *
5 * copyright ownership. *
6 * *
7 * This program and the accompanying materials are made available under the terms of the Eclipse *
8 * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 *
9 * *
10 * SPDX-License-Identifier: EPL-2.0 *
11 **************************************************************************************************/
12
14
15/* Calypsonet Terminal Calypso */
16#include "InconsistentDataException.h"
17
18/* Keyple Card Calypso */
19#include "CalypsoCardCommand.h"
20#include "CalypsoCardConstant.h"
22#include "CardPinException.h"
23#include "CmdCardGetDataFci.h"
24#include "CmdCardGetDataFcp.h"
26#include "CmdCardSelectFile.h"
28
29/* Keyple Core Util */
30#include "Arrays.h"
31#include "IllegalStateException.h"
32#include "System.h"
33
34namespace keyple {
35namespace card {
36namespace calypso {
37
38using namespace calypsonet::terminal::calypso::transaction;
39using namespace keyple::core::util::cpp;
40using namespace keyple::core::util::cpp::exception;
41
42CalypsoCardUtilAdapter::CalypsoCardUtilAdapter() {}
43
45 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
46 const std::shared_ptr<AbstractCardCommand> command,
47 const std::shared_ptr<ApduResponseApi> apduResponse,
48 const bool isSessionOpen)
49{
50 if (command->getCommandRef() == CalypsoCardCommand::READ_RECORDS) {
51 updateCalypsoCardReadRecords(calypsoCard,
52 std::dynamic_pointer_cast<CmdCardReadRecords>(command),
53 apduResponse,
54 isSessionOpen);
55 } else if (command->getCommandRef() == CalypsoCardCommand::GET_DATA) {
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),
63 apduResponse);
64 } else if (std::dynamic_pointer_cast<CmdCardGetDataTraceabilityInformation>(command)) {
65 updateCalypsoCardWithTraceabilityInformation(
66 calypsoCard,
67 std::dynamic_pointer_cast<CmdCardGetDataTraceabilityInformation>(command),
68 apduResponse);
69 } else {
70 throw IllegalStateException("Unknown GET DATA command reference.");
71 }
72 } else if (command->getCommandRef() == CalypsoCardCommand::SEARCH_RECORD_MULTIPLE) {
73 updateCalypsoCardSearchRecordMultiple(
74 calypsoCard,
75 std::dynamic_pointer_cast<CmdCardSearchRecordMultiple>(command),
76 apduResponse,
77 isSessionOpen);
78 } else if (command->getCommandRef() == CalypsoCardCommand::READ_RECORD_MULTIPLE) {
79 updateCalypsoCardReadRecordMultiple(
80 calypsoCard,
81 std::dynamic_pointer_cast<CmdCardReadRecordMultiple>(command),
82 apduResponse,
83 isSessionOpen);
84 } else if (command->getCommandRef() == CalypsoCardCommand::SELECT_FILE) {
85 updateCalypsoCardWithFcp(calypsoCard, command, apduResponse);
86 } else if (command->getCommandRef() == CalypsoCardCommand::UPDATE_RECORD) {
87 updateCalypsoCardUpdateRecord(
88 calypsoCard,
89 std::dynamic_pointer_cast<CmdCardUpdateRecord>(command),
90 apduResponse);
91 } else if (command->getCommandRef() == CalypsoCardCommand::WRITE_RECORD) {
92 updateCalypsoCardWriteRecord(
93 calypsoCard,
94 std::dynamic_pointer_cast<CmdCardWriteRecord>(command),
95 apduResponse);
96 } else if (command->getCommandRef() == CalypsoCardCommand::APPEND_RECORD) {
97 updateCalypsoCardAppendRecord(
98 calypsoCard,
99 std::dynamic_pointer_cast<CmdCardAppendRecord>(command),
100 apduResponse);
101 } else if (command->getCommandRef() == CalypsoCardCommand::INCREASE ||
102 command->getCommandRef() == CalypsoCardCommand::DECREASE) {
103 updateCalypsoCardIncreaseOrDecrease(
104 calypsoCard,
105 std::dynamic_pointer_cast<CmdCardIncreaseOrDecrease>(command),
106 apduResponse);
107 } else if (command->getCommandRef() == CalypsoCardCommand::INCREASE_MULTIPLE ||
108 command->getCommandRef() == CalypsoCardCommand::DECREASE_MULTIPLE) {
109 updateCalypsoCardIncreaseOrDecreaseMultiple(
110 calypsoCard,
111 std::dynamic_pointer_cast<CmdCardIncreaseOrDecreaseMultiple>(command),
112 apduResponse);
113 } else if (command->getCommandRef() == CalypsoCardCommand::OPEN_SESSION) {
114 updateCalypsoCardOpenSession(
115 calypsoCard,
116 std::dynamic_pointer_cast<CmdCardOpenSession>(command),
117 apduResponse);
118 } else if (command->getCommandRef() == CalypsoCardCommand::CLOSE_SESSION) {
119 updateCalypsoCardCloseSession(
120 std::dynamic_pointer_cast<CmdCardCloseSession>(command),
121 apduResponse);
122 } else if (command->getCommandRef() == CalypsoCardCommand::READ_BINARY) {
123 updateCalypsoCardReadBinary(
124 calypsoCard,
125 std::dynamic_pointer_cast<CmdCardReadBinary>(command),
126 apduResponse,
127 isSessionOpen);
128 } else if (command->getCommandRef() == CalypsoCardCommand::UPDATE_BINARY) {
129 updateCalypsoCardUpdateBinary(
130 calypsoCard,
131 std::dynamic_pointer_cast<CmdCardUpdateOrWriteBinary>(command),
132 apduResponse);
133 } else if (command->getCommandRef() == CalypsoCardCommand::WRITE_BINARY) {
134 updateCalypsoCardWriteBinary(
135 calypsoCard,
136 std::dynamic_pointer_cast<CmdCardUpdateOrWriteBinary>(command),
137 apduResponse);
138 } else if (command->getCommandRef() == CalypsoCardCommand::GET_CHALLENGE) {
139 updateCalypsoCardGetChallenge(
140 calypsoCard,
141 std::dynamic_pointer_cast<CmdCardGetChallenge>(command),
142 apduResponse);
143 } else if (command->getCommandRef() == CalypsoCardCommand::VERIFY_PIN) {
144 updateCalypsoVerifyPin(
145 calypsoCard,
146 std::dynamic_pointer_cast<CmdCardVerifyPin>(command),
147 apduResponse);
148 } else if (command->getCommandRef() == CalypsoCardCommand::SV_GET) {
149 updateCalypsoCardSvGet(
150 calypsoCard,
151 std::dynamic_pointer_cast<CmdCardSvGet>(command),
152 apduResponse);
153 } else if (command->getCommandRef() == CalypsoCardCommand::SV_RELOAD ||
154 command->getCommandRef() == CalypsoCardCommand::SV_DEBIT ||
155 command->getCommandRef() == CalypsoCardCommand::SV_UNDEBIT) {
156 updateCalypsoCardSvOperation(calypsoCard, command, apduResponse);
157 } else if (command->getCommandRef() == CalypsoCardCommand::INVALIDATE ||
158 command->getCommandRef() == CalypsoCardCommand::REHABILITATE) {
159 updateCalypsoInvalidateRehabilitate(command, apduResponse);
160 } else if (command->getCommandRef() == CalypsoCardCommand::CHANGE_PIN) {
161 updateCalypsoChangePin(std::dynamic_pointer_cast<CmdCardChangePin>(command), apduResponse);
162 } else if (command->getCommandRef() == CalypsoCardCommand::CHANGE_KEY) {
163 updateCalypsoChangeKey(std::dynamic_pointer_cast<CmdCardChangeKey>(command), apduResponse);
164 } else {
165 throw IllegalStateException("Unknown command reference.");
166 }
167}
168
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)
174{
175 /*
176 * If there are more responses than requests, then we are unable to fill the card image. In this
177 * case we stop processing immediately because it may be a case of fraud, and we throw a
178 * desynchronized exception.
179 */
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()));
186 }
187
188 /*
189 * We go through all the responses (and not the requests) because there may be fewer in the case
190 * of an error that occurred in strict mode. In this case the last response will raise an
191 * exception.
192 */
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++);
197 updateCalypsoCard(calypsoCard, command, apduResponse, isSessionOpen);
198 }
199
200 /*
201 * Finally, if no error has occurred and there are fewer responses than requests, then we
202 * throw a desynchronized exception.
203 */
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()));
210 }
211}
212
213void CalypsoCardUtilAdapter::updateCalypsoCardOpenSession(
214 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
215 std::shared_ptr<CmdCardOpenSession> cmdCardOpenSession,
216 const std::shared_ptr<ApduResponseApi> apduResponse)
217{
218 cmdCardOpenSession->setApduResponse(apduResponse).checkStatus();
219
220 /* CL-CSS-INFORAT.1 */
221 calypsoCard->setDfRatified(cmdCardOpenSession->wasRatified());
222 /* CL-CSS-INFOTCNT.1 */
223 calypsoCard->setTransactionCounter(cmdCardOpenSession->getTransactionCounterValue());
224
225 const std::vector<uint8_t>& recordDataRead = cmdCardOpenSession->getRecordDataRead();
226
227 if (recordDataRead.size() > 0) {
228 calypsoCard->setContent(cmdCardOpenSession->getSfi(),
229 cmdCardOpenSession->getRecordNumber(),
230 recordDataRead);
231 }
232}
233
234void CalypsoCardUtilAdapter::updateCalypsoCardCloseSession(
235 std::shared_ptr<CmdCardCloseSession> cmdCardCloseSession,
236 const std::shared_ptr<ApduResponseApi> apduResponse)
237{
238 cmdCardCloseSession->setApduResponse(apduResponse).checkStatus();
239}
240
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)
246{
247 cmdCardReadRecords->setApduResponse(apduResponse);
248 checkResponseStatusForStrictAndBestEffortMode(cmdCardReadRecords, isSessionOpen);
249
250 /* Iterate over read records to fill the CalypsoCard */
251 for (const auto& entry : cmdCardReadRecords->getRecords()) {
252 calypsoCard->setContent(cmdCardReadRecords->getSfi(), entry.first, entry.second);
253 }
254}
255
256void CalypsoCardUtilAdapter::checkResponseStatusForStrictAndBestEffortMode(
257 const std::shared_ptr<AbstractCardCommand> command, const bool isSessionOpen)
258{
259 if (isSessionOpen) {
260 command->checkStatus();
261 } else {
262 try {
263 command->checkStatus();
264 } catch (const CardDataAccessException& e) {
265 /*
266 * Best effort mode, do not throw exception for "file not found" and "record not found"
267 * errors.
268 */
269 if (command->getApduResponse()->getStatusWord() != 0x6A82 &&
270 command->getApduResponse()->getStatusWord() != 0x6A83) {
271 throw e;
272 }
273 }
274 }
275}
276
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)
282{
283
284 cmdCardSearchRecordMultiple->setApduResponse(apduResponse);
285 checkResponseStatusForStrictAndBestEffortMode(cmdCardSearchRecordMultiple, isSessionOpen);
286
287 if (cmdCardSearchRecordMultiple->getFirstMatchingRecordContent().size() > 0) {
288 calypsoCard->setContent(
289 cmdCardSearchRecordMultiple->getSearchCommandData()->getSfi(),
290 cmdCardSearchRecordMultiple->getSearchCommandData()->getMatchingRecordNumbers()[0],
291 cmdCardSearchRecordMultiple->getFirstMatchingRecordContent());
292 }
293}
294
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)
300{
301 cmdCardReadRecordMultiple->setApduResponse(apduResponse);
302 checkResponseStatusForStrictAndBestEffortMode(cmdCardReadRecordMultiple, isSessionOpen);
303
304 for (const auto& entry : cmdCardReadRecordMultiple->getResults()) {
305 calypsoCard->setContent(cmdCardReadRecordMultiple->getSfi(),
306 entry.first,
307 entry.second,
308 cmdCardReadRecordMultiple->getOffset());
309 }
310}
311
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)
317{
318
319 cmdCardReadBinary->setApduResponse(apduResponse);
320 checkResponseStatusForStrictAndBestEffortMode(cmdCardReadBinary, isSessionOpen);
321
322 calypsoCard->setContent(cmdCardReadBinary->getSfi(),
323 1,
324 apduResponse->getDataOut(),
325 cmdCardReadBinary->getOffset());
326}
327
328void CalypsoCardUtilAdapter::updateCalypsoCardWithFcp(
329 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
330 std::shared_ptr<AbstractCardCommand> command,
331 const std::shared_ptr<ApduResponseApi> apduResponse)
332{
333
334 command->setApduResponse(apduResponse).checkStatus();
335
336 std::vector<uint8_t> proprietaryInformation;
337 if (command->getCommandRef() == CalypsoCardCommand::SELECT_FILE) {
338 proprietaryInformation =
339 std::dynamic_pointer_cast<CmdCardSelectFile>(command)->getProprietaryInformation();
340 } else {
341 proprietaryInformation =
342 std::dynamic_pointer_cast<CmdCardGetDataFcp>(command)->getProprietaryInformation();
343 }
344
345 const uint8_t sfi = proprietaryInformation[CalypsoCardConstant::SEL_SFI_OFFSET];
346 const uint8_t fileType = proprietaryInformation[CalypsoCardConstant::SEL_TYPE_OFFSET];
347
348 if (fileType == CalypsoCardConstant::FILE_TYPE_MF ||
350 const auto directoryHeader = createDirectoryHeader(proprietaryInformation);
351 calypsoCard->setDirectoryHeader(directoryHeader);
352 } else if (fileType == CalypsoCardConstant::FILE_TYPE_EF) {
353 auto fileHeader = createFileHeader(proprietaryInformation);
354 calypsoCard->setFileHeader(sfi, fileHeader);
355 } else {
356 throw IllegalStateException("Unknown file type: " + std::to_string(fileType));
357 }
358}
359
360void CalypsoCardUtilAdapter::updateCalypsoCardWithEfList(
361 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
362 std::shared_ptr<CmdCardGetDataEfList> command,
363 const std::shared_ptr<ApduResponseApi> apduResponse)
364{
365
366 command->setApduResponse(apduResponse).checkStatus();
367
368 const std::map<const std::shared_ptr<FileHeaderAdapter>, const uint8_t> fileHeaderToSfiMap =
369 command->getEfHeaders();
370
371 for (const auto& entry : fileHeaderToSfiMap) {
372 calypsoCard->setFileHeader(entry.second, entry.first);
373 }
374}
375
376void CalypsoCardUtilAdapter::updateCalypsoCardWithTraceabilityInformation(
377 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
378 std::shared_ptr<CmdCardGetDataTraceabilityInformation> command,
379 const std::shared_ptr<ApduResponseApi> apduResponse)
380{
381
382 command->setApduResponse(apduResponse).checkStatus();
383
384 calypsoCard->setTraceabilityInformation(apduResponse->getDataOut());
385}
386
387void CalypsoCardUtilAdapter::updateCalypsoCardUpdateRecord(
388 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
389 std::shared_ptr<CmdCardUpdateRecord> cmdCardUpdateRecord,
390 const std::shared_ptr<ApduResponseApi> apduResponse)
391{
392 cmdCardUpdateRecord->setApduResponse(apduResponse).checkStatus();
393
394 calypsoCard->setContent(cmdCardUpdateRecord->getSfi(),
395 cmdCardUpdateRecord->getRecordNumber(),
396 cmdCardUpdateRecord->getData());
397}
398
399void CalypsoCardUtilAdapter::updateCalypsoCardWriteRecord(
400 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
401 std::shared_ptr<CmdCardWriteRecord> cmdCardWriteRecord,
402 const std::shared_ptr<ApduResponseApi> apduResponse)
403{
404
405 cmdCardWriteRecord->setApduResponse(apduResponse).checkStatus();
406
407 calypsoCard->fillContent(cmdCardWriteRecord->getSfi(),
408 cmdCardWriteRecord->getRecordNumber(),
409 cmdCardWriteRecord->getData(),
410 0);
411}
412
413void CalypsoCardUtilAdapter::updateCalypsoCardUpdateBinary(
414 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
415 std::shared_ptr<CmdCardUpdateOrWriteBinary> cmdCardUpdateBinary,
416 const std::shared_ptr<ApduResponseApi> apduResponse)
417{
418 cmdCardUpdateBinary->setApduResponse(apduResponse).checkStatus();
419
420 calypsoCard->setContent(cmdCardUpdateBinary->getSfi(),
421 1,
422 cmdCardUpdateBinary->getData(),
423 cmdCardUpdateBinary->getOffset());
424}
425
426void CalypsoCardUtilAdapter::updateCalypsoCardWriteBinary(
427 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
428 std::shared_ptr<CmdCardUpdateOrWriteBinary> cmdCardWriteBinary,
429 const std::shared_ptr<ApduResponseApi> apduResponse)
430{
431 cmdCardWriteBinary->setApduResponse(apduResponse).checkStatus();
432
433 calypsoCard->fillContent(cmdCardWriteBinary->getSfi(),
434 1,
435 cmdCardWriteBinary->getData(),
436 cmdCardWriteBinary->getOffset());
437}
438
439void CalypsoCardUtilAdapter::updateCalypsoCardAppendRecord(
440 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
441 std::shared_ptr<CmdCardAppendRecord> cmdCardAppendRecord,
442 const std::shared_ptr<ApduResponseApi> apduResponse)
443{
444 cmdCardAppendRecord->setApduResponse(apduResponse).checkStatus();
445
446 calypsoCard->addCyclicContent(cmdCardAppendRecord->getSfi(), cmdCardAppendRecord->getData());
447}
448
449void CalypsoCardUtilAdapter::updateCalypsoCardIncreaseOrDecrease(
450 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
451 std::shared_ptr<CmdCardIncreaseOrDecrease> cmdCardIncreaseOrDecrease,
452 const std::shared_ptr<ApduResponseApi> apduResponse)
453{
454
455 cmdCardIncreaseOrDecrease->setApduResponse(apduResponse).checkStatus();
456
457 calypsoCard->setCounter(cmdCardIncreaseOrDecrease->getSfi(),
458 cmdCardIncreaseOrDecrease->getCounterNumber(),
459 apduResponse->getDataOut());
460}
461
462void CalypsoCardUtilAdapter::updateCalypsoCardIncreaseOrDecreaseMultiple(
463 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
464 std::shared_ptr<CmdCardIncreaseOrDecreaseMultiple> cmdCardIncreaseOrDecreaseMultiple,
465 const std::shared_ptr<ApduResponseApi> apduResponse)
466{
467
468 cmdCardIncreaseOrDecreaseMultiple->setApduResponse(apduResponse).checkStatus();
469
470 for (const auto& entry : cmdCardIncreaseOrDecreaseMultiple->getNewCounterValues()) {
471 calypsoCard->setCounter(cmdCardIncreaseOrDecreaseMultiple->getSfi(),
472 entry.first,
473 entry.second);
474 }
475}
476
477void CalypsoCardUtilAdapter::updateCalypsoCardGetChallenge(
478 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
479 std::shared_ptr<CmdCardGetChallenge> cmdCardGetChallenge,
480 const std::shared_ptr<ApduResponseApi> apduResponse)
481{
482 cmdCardGetChallenge->setApduResponse(apduResponse).checkStatus();
483 calypsoCard->setCardChallenge(cmdCardGetChallenge->getCardChallenge());
484}
485
486void CalypsoCardUtilAdapter::updateCalypsoVerifyPin(
487 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
488 std::shared_ptr<CmdCardVerifyPin> cmdCardVerifyPin,
489 const std::shared_ptr<ApduResponseApi> apduResponse)
490{
491 cmdCardVerifyPin->setApduResponse(apduResponse);
492 calypsoCard->setPinAttemptRemaining(cmdCardVerifyPin->getRemainingAttemptCounter());
493
494 try {
495 cmdCardVerifyPin->checkStatus();
496 } catch (const CardPinException& ex) {
497 /*
498 * Forward the exception if the operation do not target the reading of the attempt counter.
499 * Catch it silently otherwise
500 */
501 if (!cmdCardVerifyPin->isReadCounterOnly()) {
502 throw ex;
503 }
504 }
505}
506
507void CalypsoCardUtilAdapter::updateCalypsoChangePin(
508 std::shared_ptr<CmdCardChangePin> cmdCardChangePin,
509 const std::shared_ptr<ApduResponseApi> apduResponse)
510{
511 cmdCardChangePin->setApduResponse(apduResponse).checkStatus();
512}
513
514void CalypsoCardUtilAdapter::updateCalypsoChangeKey(
515 std::shared_ptr<CmdCardChangeKey> cmdCardChangeKey,
516 const std::shared_ptr<ApduResponseApi> apduResponse)
517{
518 cmdCardChangeKey->setApduResponse(apduResponse).checkStatus();
519}
520
521void CalypsoCardUtilAdapter::updateCalypsoCardSvGet(
522 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
523 std::shared_ptr<CmdCardSvGet> cmdCardSvGet,
524 const std::shared_ptr<ApduResponseApi> apduResponse)
525{
526 cmdCardSvGet->setApduResponse(apduResponse).checkStatus();
527
528 calypsoCard->setSvData(cmdCardSvGet->getCurrentKVC(),
529 cmdCardSvGet->getSvGetCommandHeader(),
530 cmdCardSvGet->getApduResponse()->getApdu(),
531 cmdCardSvGet->getBalance(),
532 cmdCardSvGet->getTransactionNumber(),
533 cmdCardSvGet->getLoadLog(),
534 cmdCardSvGet->getDebitLog());
535}
536
537void CalypsoCardUtilAdapter::updateCalypsoCardSvOperation(
538 std::shared_ptr<CalypsoCardAdapter> calypsoCard,
539 std::shared_ptr<AbstractCardCommand> cmdCardSvOperation,
540 const std::shared_ptr<ApduResponseApi> apduResponse)
541{
542 cmdCardSvOperation->setApduResponse(apduResponse).checkStatus();
543 calypsoCard->setSvOperationSignature(cmdCardSvOperation->getApduResponse()->getDataOut());
544}
545
546void CalypsoCardUtilAdapter::updateCalypsoInvalidateRehabilitate(
547 std::shared_ptr<AbstractCardCommand> cmdCardInvalidateRehabilitate,
548 const std::shared_ptr<ApduResponseApi> apduResponse)
549{
550 cmdCardInvalidateRehabilitate->setApduResponse(apduResponse).checkStatus();
551}
552
553const std::shared_ptr<DirectoryHeader> CalypsoCardUtilAdapter::createDirectoryHeader(
554 const std::vector<uint8_t>& proprietaryInformation)
555{
556 std::vector<uint8_t> accessConditions(CalypsoCardConstant::SEL_AC_LENGTH);
557 System::arraycopy(proprietaryInformation,
559 accessConditions,
560 0,
562
563 std::vector<uint8_t> keyIndexes(CalypsoCardConstant::SEL_NKEY_LENGTH);
564 System::arraycopy(proprietaryInformation,
566 keyIndexes,
567 0,
569
570 const uint8_t dfStatus = proprietaryInformation[CalypsoCardConstant::SEL_DF_STATUS_OFFSET];
571
572 uint16_t lid = (((proprietaryInformation[CalypsoCardConstant::SEL_LID_OFFSET] << 8) & 0xff00) |
573 (proprietaryInformation[CalypsoCardConstant::SEL_LID_OFFSET + 1] & 0x00ff));
574
576 ->lid(lid)
577 .accessConditions(accessConditions)
578 .keyIndexes(keyIndexes)
579 .dfStatus(dfStatus)
580 .kvc(WriteAccessLevel::PERSONALIZATION,
581 proprietaryInformation[CalypsoCardConstant::SEL_KVCS_OFFSET])
582 .kvc(WriteAccessLevel::LOAD,
583 proprietaryInformation[CalypsoCardConstant::SEL_KVCS_OFFSET + 1])
584 .kvc(WriteAccessLevel::DEBIT,
585 proprietaryInformation[CalypsoCardConstant::SEL_KVCS_OFFSET + 2])
586 .kif(WriteAccessLevel::PERSONALIZATION,
587 proprietaryInformation[CalypsoCardConstant::SEL_KIFS_OFFSET])
588 .kif(WriteAccessLevel::LOAD,
589 proprietaryInformation[CalypsoCardConstant::SEL_KIFS_OFFSET + 1])
590 .kif(WriteAccessLevel::DEBIT,
591 proprietaryInformation[CalypsoCardConstant::SEL_KIFS_OFFSET + 2])
592 .build();
593}
594
595ElementaryFile::Type CalypsoCardUtilAdapter::getEfTypeFromCardValue(const uint8_t efType)
596{
597 ElementaryFile::Type fileType;
598
600 fileType = ElementaryFile::Type::BINARY;
601 } else if (efType == CalypsoCardConstant::EF_TYPE_LINEAR) {
602 fileType = ElementaryFile::Type::LINEAR;
603 } else if (efType == CalypsoCardConstant::EF_TYPE_CYCLIC) {
604 fileType = ElementaryFile::Type::CYCLIC;
606 fileType = ElementaryFile::Type::SIMULATED_COUNTERS;
607 } else if (efType == CalypsoCardConstant::EF_TYPE_COUNTERS) {
608 fileType = ElementaryFile::Type::COUNTERS;
609 } else {
610 throw IllegalStateException("Unknown EF Type: " + std::to_string(efType));
611 }
612
613 return fileType;
614}
615
616const std::shared_ptr<FileHeaderAdapter> CalypsoCardUtilAdapter::createFileHeader(
617 const std::vector<uint8_t>& proprietaryInformation)
618{
619 const ElementaryFile::Type fileType =
620 getEfTypeFromCardValue(proprietaryInformation[CalypsoCardConstant::SEL_EF_TYPE_OFFSET]);
621
622 int recordSize;
623 int recordsNumber;
624
625 if (fileType == ElementaryFile::Type::BINARY) {
626 recordSize =
627 ((proprietaryInformation[CalypsoCardConstant::SEL_REC_SIZE_OFFSET] << 8) & 0x0000ff00) |
628 (proprietaryInformation[CalypsoCardConstant::SEL_NUM_REC_OFFSET] & 0x000000ff);
629 recordsNumber = 1;
630 } else {
631 recordSize = proprietaryInformation[CalypsoCardConstant::SEL_REC_SIZE_OFFSET];
632 recordsNumber = proprietaryInformation[CalypsoCardConstant::SEL_NUM_REC_OFFSET];
633 }
634
635 std::vector<uint8_t> accessConditions(CalypsoCardConstant::SEL_AC_LENGTH);
636 System::arraycopy(proprietaryInformation,
638 accessConditions,
639 0,
641
642 std::vector<uint8_t> keyIndexes(CalypsoCardConstant::SEL_NKEY_LENGTH);
643 System::arraycopy(proprietaryInformation,
645 keyIndexes,
646 0,
648
649 const uint8_t dfStatus = proprietaryInformation[CalypsoCardConstant::SEL_DF_STATUS_OFFSET];
650
651 const uint16_t sharedReference =
652 ((proprietaryInformation[CalypsoCardConstant::SEL_DATA_REF_OFFSET] << 8) & 0xff00) |
653 (proprietaryInformation[CalypsoCardConstant::SEL_DATA_REF_OFFSET + 1] & 0x00ff);
654
655 const uint16_t lid =
656 ((proprietaryInformation[CalypsoCardConstant::SEL_LID_OFFSET] << 8) & 0xff00) |
657 (proprietaryInformation[CalypsoCardConstant::SEL_LID_OFFSET + 1] & 0x00ff);
658
659 return FileHeaderAdapter::builder()->lid(lid)
660 .recordsNumber(recordsNumber)
661 .recordSize(recordSize)
662 .type(fileType)
663 .accessConditions(accessConditions)
664 .keyIndexes(keyIndexes)
665 .dfStatus(dfStatus)
666 .sharedReference(sharedReference)
667 .build();
668}
669
670}
671}
672}
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 void updateCalypsoCard(std::shared_ptr< CalypsoCardAdapter > calypsoCard, const std::shared_ptr< AbstractCardCommand > command, const std::shared_ptr< ApduResponseApi > apduResponse, const bool isSessionOpen)
static std::shared_ptr< DirectoryHeaderBuilder > builder()
static std::shared_ptr< FileHeaderBuilder > builder()