14#include "keyple/card/calypso/CalypsoCardAdapter.hpp"
22#include "keyple/card/calypso/CalypsoCardClass.hpp"
23#include "keyple/card/calypso/CalypsoCardConstant.hpp"
24#include "keyple/card/calypso/DtoAdapters.hpp"
25#include "keyple/core/util/ByteArrayUtil.hpp"
26#include "keyple/core/util/HexUtil.hpp"
27#include "keyple/core/util/cpp/KeypleStd.hpp"
28#include "keyple/core/util/cpp/System.hpp"
29#include "keyple/core/util/cpp/exception/IllegalArgumentException.hpp"
30#include "keyple/core/util/cpp/exception/IllegalStateException.hpp"
31#include "keypop/card/CardSelectionResponseApi.hpp"
37using keyple::core::util::ByteArrayUtil;
38using keyple::core::util::HexUtil;
39using keyple::core::util::cpp::System;
40using keyple::core::util::cpp::exception::IllegalArgumentException;
41using keyple::core::util::cpp::exception::IllegalStateException;
42using keypop::card::CardSelectionResponseApi;
44const int CalypsoCardAdapter::CARD_REV1_ATR_LENGTH = 20;
45const int CalypsoCardAdapter ::
46 REV1_CARD_DEFAULT_WRITE_OPERATIONS_NUMBER_SUPPORTED_PER_SESSION = 3;
47const int CalypsoCardAdapter ::
48 REV2_CARD_DEFAULT_WRITE_OPERATIONS_NUMBER_SUPPORTED_PER_SESSION = 6;
49const int CalypsoCardAdapter::SI_BUFFER_SIZE_INDICATOR = 0;
50const int CalypsoCardAdapter::SI_PLATFORM = 1;
51const int CalypsoCardAdapter::SI_APPLICATION_TYPE = 2;
52const int CalypsoCardAdapter::SI_APPLICATION_SUBTYPE = 3;
53const int CalypsoCardAdapter::SI_SOFTWARE_ISSUER = 4;
54const int CalypsoCardAdapter::SI_SOFTWARE_VERSION = 5;
55const int CalypsoCardAdapter::SI_SOFTWARE_REVISION = 6;
56const int CalypsoCardAdapter::DEFAULT_PAYLOAD_CAPACITY = 250;
58const uint8_t CalypsoCardAdapter::APP_TYPE_WITH_CALYPSO_PIN = 0x01;
59const uint8_t CalypsoCardAdapter::APP_TYPE_WITH_CALYPSO_SV = 0x02;
60const uint8_t CalypsoCardAdapter::APP_TYPE_RATIFICATION_COMMAND_REQUIRED = 0x04;
61const uint8_t CalypsoCardAdapter::APP_TYPE_CALYPSO_REV_32_MODE = 0x08;
62const uint8_t CalypsoCardAdapter::APP_TYPE_WITH_PUBLIC_AUTHENTICATION = 0x10;
64const std::vector<int> CalypsoCardAdapter::BUFFER_SIZE_INDICATOR_TO_BUFFER_SIZE
65 = {0, 0, 0, 0, 0, 0, 215, 256,
66 304, 362, 430, 512, 608, 724, 861, 1024,
67 1217, 1448, 1722, 2048, 2435, 2896, 3444, 4096,
68 4870, 5792, 6888, 8192, 9741, 11585, 13777, 16384,
69 19483, 23170, 27554, 32768, 38967, 46340, 55108, 65536,
70 77935, 92681, 110217, 131072, 155871, 185363, 220435, 262144,
71 311743, 370727, 440871, 524288, 623487, 741455, 881743, 1048576};
73const std::vector<std::shared_ptr<CalypsoCardAdapter::PatchRev3>>
74 CalypsoCardAdapter::mPatchesRev3 = initPatchRev3();
75const std::vector<std::shared_ptr<CalypsoCardAdapter::PatchRev12>>
76 CalypsoCardAdapter::mPatchesRev12 = initPatchRev12();
78CalypsoCardAdapter::CalypsoCardAdapter()
83CalypsoCardAdapter::initialize(
84 const std::shared_ptr<CardSelectionResponseApi> cardSelectionResponse)
86 if (cardSelectionResponse !=
nullptr) {
87 if (cardSelectionResponse->getSelectApplicationResponse() !=
nullptr) {
89 cardSelectionResponse->getSelectApplicationResponse());
91 }
else if (cardSelectionResponse->getPowerOnData() != std::string(
"")) {
92 initializeWithPowerOnData(cardSelectionResponse->getPowerOnData());
97const std::vector<std::shared_ptr<CalypsoCardAdapter::PatchRev12>>
98CalypsoCardAdapter::initPatchRev12()
100 std::shared_ptr<PatchRev12> p12 =
nullptr;
101 std::vector<std::shared_ptr<PatchRev12>> v12;
106 p12 = std::shared_ptr<PatchRev12>(
107 new PatchRev12(
"03080304000200",
"FFFFFFFFFFFFFF"));
108 p12->setLegacyCase1();
114const std::vector<std::shared_ptr<CalypsoCardAdapter::PatchRev3>>
115CalypsoCardAdapter::initPatchRev3()
117 std::shared_ptr<PatchRev3> p3 =
nullptr;
118 std::vector<std::shared_ptr<PatchRev3>> v3;
123 p3 = std::shared_ptr<PatchRev3>(
124 new PatchRev3(
"003C0000001000",
"00FF000000FF00"));
125 p3->setPayloadCapacity(235);
132CalypsoCardAdapter::initializeWithPowerOnData(
const std::string& powerOnData)
134 mProductType = ProductType::PRIME_REVISION_1;
135 mCalypsoCardClass = CalypsoCardClass::LEGACY;
137 mPowerOnData = powerOnData;
143 const std::vector<uint8_t> atr = HexUtil::toByteArray(powerOnData);
148 if (atr.size() != CARD_REV1_ATR_LENGTH) {
149 throw IllegalArgumentException(
150 std::string(
"ATR is not the correct length. ")
151 +
"Expected: " + std::to_string(CARD_REV1_ATR_LENGTH) +
", "
152 +
"got: " + std::to_string(atr.size()));
156 mCalypsoSerialNumber = std::vector<uint8_t>(8);
162 System::arraycopy(atr, 12, mCalypsoSerialNumber, 4, 4);
163 mModificationsCounterMax
164 = REV1_CARD_DEFAULT_WRITE_OPERATIONS_NUMBER_SUPPORTED_PER_SESSION;
166 mStartupInfo = std::vector<uint8_t>(7);
169 mStartupInfo[0] =
static_cast<uint8_t
>(mModificationsCounterMax);
172 System::arraycopy(atr, 6, mStartupInfo, 1, 6);
174 mIsRatificationOnDeselectSupported =
true;
178CalypsoCardAdapter::initializeWithFci(
179 const std::shared_ptr<ApduResponseApi> selectApplicationResponse)
181 mSelectApplicationResponse = selectApplicationResponse;
183 if (selectApplicationResponse->getDataOut().size() == 0) {
192 auto cmdCardGetDataFci(
193 std::make_shared<CommandGetDataFci>(
194 std::make_shared<DtoAdapters::TransactionContextDto>(),
195 std::make_shared<DtoAdapters::CommandContextDto>(
false,
false)));
196 cmdCardGetDataFci->parseResponseForSelection(
197 selectApplicationResponse,
198 std::dynamic_pointer_cast<CalypsoCardAdapter>(shared_from_this()));
200 if (!cmdCardGetDataFci->isValidCalypsoFCI()) {
201 throw IllegalArgumentException(
"FCI has a bad format");
206CalypsoCardAdapter::initializeWithFci(
207 const std::shared_ptr<CommandGetDataFci>& cmdCardGetDataFci)
209 mIsDfInvalidated = cmdCardGetDataFci->isDfInvalidated();
212 mDfName = cmdCardGetDataFci->getDfName();
213 mCalypsoSerialNumber = cmdCardGetDataFci->getApplicationSerialNumber();
216 mStartupInfo = cmdCardGetDataFci->getDiscretionaryData();
225 mApplicationType = mStartupInfo[SI_APPLICATION_TYPE];
226 mProductType = computeProductType(mApplicationType & 0xFF);
229 mApplicationSubType = mStartupInfo[SI_APPLICATION_SUBTYPE];
230 if (mApplicationSubType == 0x00 || mApplicationSubType == 0xFF) {
231 throw IllegalArgumentException(
232 std::string(
"Unexpected application subtype: ")
233 + HexUtil::toHex(mApplicationSubType));
236 mSessionModification = mStartupInfo[SI_BUFFER_SIZE_INDICATOR];
238 if (mProductType == ProductType::PRIME_REVISION_2) {
239 mCalypsoCardClass = CalypsoCardClass::LEGACY;
243 mIsModificationCounterInBytes =
false;
244 mModificationsCounterMax
245 = REV2_CARD_DEFAULT_WRITE_OPERATIONS_NUMBER_SUPPORTED_PER_SESSION;
247 }
else if (mProductType == ProductType::BASIC) {
249 if (mSessionModification < 0x04 || mSessionModification > 0x37) {
250 throw IllegalArgumentException(
251 std::string(
"Wrong session modification value for a Basic type")
252 +
" (should be between 04h and 37h): "
253 + HexUtil::toHex(mSessionModification));
256 mCalypsoCardClass = CalypsoCardClass::ISO;
257 mIsModificationCounterInBytes =
false;
258 mModificationsCounterMax = 4;
260 mCalypsoCardClass = CalypsoCardClass::ISO;
266 if (mSessionModification < 0x06 || mSessionModification > 0x37) {
267 throw IllegalArgumentException(
268 "Session modifications byte should be in range [06h..47h]. "
270 + HexUtil::toHex(mSessionModification));
273 mModificationsCounterMax
274 = BUFFER_SIZE_INDICATOR_TO_BUFFER_SIZE[mSessionModification];
278 if (mProductType == ProductType::PRIME_REVISION_3) {
279 mIsExtendedModeSupported
280 = (mApplicationType & APP_TYPE_CALYPSO_REV_32_MODE) != 0;
281 mIsRatificationOnDeselectSupported
282 = (mApplicationType & APP_TYPE_RATIFICATION_COMMAND_REQUIRED) == 0;
284 = (mApplicationType & APP_TYPE_WITH_PUBLIC_AUTHENTICATION) != 0;
287 if (mProductType == ProductType::PRIME_REVISION_3
288 || mProductType == ProductType::PRIME_REVISION_2) {
289 mIsSvFeatureAvailable
290 = (mApplicationType & APP_TYPE_WITH_CALYPSO_SV) != 0;
291 mIsPinFeatureAvailable
292 = (mApplicationType & APP_TYPE_WITH_CALYPSO_PIN) != 0;
295 mIsHce = (mCalypsoSerialNumber[3] & 0x80) == 0x80;
297 if (mProductType != ProductType::PRIME_REVISION_2
298 && mProductType != ProductType::PRIME_REVISION_1) {
299 mIsCounterValuePostponed = std::make_shared<bool>(
false);
302 applyPatchIfNeeded();
305CalypsoCard::ProductType
306CalypsoCardAdapter::computeProductType(
const int applicationType)
const
308 if (applicationType == 0) {
309 throw IllegalArgumentException(
"Invalid application type 00h");
310 }
else if (applicationType == 0xFF) {
311 return ProductType::UNKNOWN;
312 }
else if (applicationType <= 0x1F) {
313 return ProductType::PRIME_REVISION_2;
314 }
else if (applicationType >= 0x90 && applicationType <= 0x97) {
315 return ProductType::LIGHT;
316 }
else if (applicationType >= 0x98 && applicationType <= 0x9F) {
317 return ProductType::BASIC;
320 return ProductType::PRIME_REVISION_3;
323const CalypsoCard::ProductType&
324CalypsoCardAdapter::getProductType()
const
330CalypsoCardAdapter::isHce()
const
335const std::vector<uint8_t>&
336CalypsoCardAdapter::getDfName()
const
341const std::vector<uint8_t>&
342CalypsoCardAdapter::getCalypsoSerialNumberFull()
const
344 return mCalypsoSerialNumber;
347const std::vector<uint8_t>
348CalypsoCardAdapter::getApplicationSerialNumber()
const
350 std::vector<uint8_t> applicationSerialNumber = mCalypsoSerialNumber;
351 applicationSerialNumber[0] = 0;
352 applicationSerialNumber[1] = 0;
354 return applicationSerialNumber;
357const std::vector<uint8_t>&
358CalypsoCardAdapter::getStartupInfoRawData()
const
364CalypsoCardAdapter::getPayloadCapacity()
const
366 return mPayloadCapacity;
370CalypsoCardAdapter::isModificationsCounterInBytes()
const
372 return mIsModificationCounterInBytes;
376CalypsoCardAdapter::getModificationsCounter()
const
378 return mModificationsCounterMax;
382CalypsoCardAdapter::getPlatform()
const
384 return mStartupInfo[SI_PLATFORM];
388CalypsoCardAdapter::getApplicationType()
const
390 return mApplicationType;
394CalypsoCardAdapter::isExtendedModeSupported()
const
396 return mIsExtendedModeSupported;
400CalypsoCardAdapter::isRatificationOnDeselectSupported()
const
402 return mIsRatificationOnDeselectSupported;
406CalypsoCardAdapter::isSvFeatureAvailable()
const
408 return mIsSvFeatureAvailable;
412CalypsoCardAdapter::isPinFeatureAvailable()
const
414 return mIsPinFeatureAvailable;
418CalypsoCardAdapter::isPkiModeSupported()
const
420 return mIsPkiModeSupported;
424CalypsoCardAdapter::getApplicationSubtype()
const
426 return mApplicationSubType;
430CalypsoCardAdapter::getSoftwareIssuer()
const
432 return mStartupInfo[SI_SOFTWARE_ISSUER];
436CalypsoCardAdapter::getSoftwareVersion()
const
438 return mStartupInfo[SI_SOFTWARE_VERSION];
442CalypsoCardAdapter::getSoftwareRevision()
const
444 return mStartupInfo[SI_SOFTWARE_REVISION];
448CalypsoCardAdapter::getSessionModification()
const
450 return mSessionModification;
453const std::vector<uint8_t>
454CalypsoCardAdapter::getTraceabilityInformation()
const
461 return mTraceabilityInformation;
464const std::vector<std::uint8_t>&
465CalypsoCardAdapter::getCardPublicKey()
const
467 return mCardPublicKey;
470const std::vector<std::uint8_t>&
471CalypsoCardAdapter::getCardCertificate()
const
473 return mCardCertificate;
476const std::vector<std::uint8_t>&
477CalypsoCardAdapter::getCaCertificate()
const
479 return mCaCertificate;
483CalypsoCardAdapter::isDfInvalidated()
const
485 return mIsDfInvalidated;
489CalypsoCardAdapter::isDfRatified()
const
491 if (mIsDfRatified !=
nullptr) {
492 return *mIsDfRatified.get();
495 throw IllegalStateException(
496 "Unable to determine the ratification status. No session was opened");
500CalypsoCardAdapter::getTransactionCounter()
const
502 if (mTransactionCounter ==
nullptr) {
503 throw IllegalStateException(
504 "Unable to determine the transaction counter. No session was "
508 return *mTransactionCounter.get();
512CalypsoCardAdapter::setTransactionCounter(
const int transactionCounter)
514 mTransactionCounter = std::make_shared<int>(transactionCounter);
518CalypsoCardAdapter::setSvData(
520 const std::vector<uint8_t>& svGetHeader,
521 const std::vector<uint8_t>& svGetData,
526 mSvGetHeader = svGetHeader;
527 mSvGetData = svGetData;
528 mSvBalance = std::make_shared<int>(svBalance);
529 mSvLastTNum = svLastTNum;
533CalypsoCardAdapter::updateSvData(
int svBalance,
int svLastTNum)
535 *mSvBalance = svBalance;
536 mSvLastTNum = svLastTNum;
540CalypsoCardAdapter::getSvBalance()
const
542 if (mSvBalance ==
nullptr) {
543 throw IllegalStateException(
"No SV Get command has been executed");
546 return *mSvBalance.get();
550CalypsoCardAdapter::getSvLastTNum()
const
552 if (mSvBalance ==
nullptr) {
553 new IllegalStateException(
"No SV Get command has been executed");
559const std::shared_ptr<SvLoadLogRecord>
560CalypsoCardAdapter::getSvLoadLogRecord()
563 const std::shared_ptr<ElementaryFile> ef
564 = getFileBySfi(CalypsoCardConstant::SV_RELOAD_LOG_FILE_SFI);
566 const std::vector<uint8_t> logRecord = ef->getData()->getContent();
567 return std::make_shared<DtoAdapters::SvLoadLogRecordAdapter>(
574const std::shared_ptr<SvDebitLogRecord>
575CalypsoCardAdapter::getSvDebitLogLastRecord()
578 const std::vector<std::shared_ptr<SvDebitLogRecord>> svDebitLogRecords
579 = getSvDebitLogAllRecords();
580 if (!svDebitLogRecords.empty()) {
581 return svDebitLogRecords[0];
587const std::vector<std::shared_ptr<SvDebitLogRecord>>
588CalypsoCardAdapter::getSvDebitLogAllRecords()
const
590 std::vector<std::shared_ptr<SvDebitLogRecord>> svDebitLogRecords;
593 const std::shared_ptr<ElementaryFile> ef
594 = getFileBySfi(CalypsoCardConstant::SV_DEBIT_LOG_FILE_SFI);
596 return svDebitLogRecords;
599 const std::map<const uint8_t, std::vector<uint8_t>>& logRecords
600 = ef->getData()->getAllRecordsContent();
601 for (
const auto& entry : logRecords) {
602 svDebitLogRecords.push_back(
603 std::make_shared<DtoAdapters::SvDebitLogRecordAdapter>(
607 return svDebitLogRecords;
611CalypsoCardAdapter::setDfRatified(
const bool dfRatified)
613 mIsDfRatified = std::make_shared<bool>(dfRatified);
617CalypsoCardAdapter::getCardClass()
const
619 return mCalypsoCardClass;
622const std::shared_ptr<DirectoryHeader>
623CalypsoCardAdapter::getDirectoryHeader()
const
625 return mDirectoryHeader;
629CalypsoCardAdapter::setDirectoryHeader(
630 std::unique_ptr<DirectoryHeader> directoryHeader)
632 mDirectoryHeader = std::move(directoryHeader);
633 mIsDfInvalidated = (mDirectoryHeader->getDfStatus() & 0x01) != 0;
638const std::shared_ptr<ElementaryFile>
639CalypsoCardAdapter::getFileBySfi(
const uint8_t sfi)
const
645 for (
const auto& ef : mFiles) {
646 if (ef->getSfi() == sfi) {
651 mLogger->warn(
"EF not found [sfi=%]\n", HexUtil::toHex(sfi));
656const std::shared_ptr<ElementaryFile>
657CalypsoCardAdapter::getFileByLid(
const uint16_t lid)
const
659 for (
const auto& ef : mFiles) {
660 if (ef->getHeader() !=
nullptr && ef->getHeader()->getLid() == lid) {
665 mLogger->warn(
"EF not found [lid=%]\n", HexUtil::toHex(lid));
670const std::vector<std::shared_ptr<ElementaryFile>>&
671CalypsoCardAdapter::getFiles()
const
676const std::shared_ptr<ElementaryFileAdapter>
677CalypsoCardAdapter::getOrCreateFile(
678 const std::uint8_t sfi,
const std::uint16_t lid)
680 if (sfi == 0 && lid == 0 && mCurrentEf !=
nullptr) {
686 for (
const auto& ef : mFiles) {
687 if (ef->getSfi() == sfi) {
689 = std::dynamic_pointer_cast<ElementaryFileAdapter>(ef);
694 }
else if (lid != 0) {
696 for (
const auto& ef : mFiles) {
697 if (ef->getHeader() !=
nullptr
698 && ef->getHeader()->getLid() == lid) {
700 = std::dynamic_pointer_cast<ElementaryFileAdapter>(ef);
707 mCurrentEf = std::make_shared<ElementaryFileAdapter>(sfi);
708 mFiles.push_back(mCurrentEf);
714CalypsoCardAdapter::isPinBlocked()
const
716 return getPinAttemptRemaining() == 0;
720CalypsoCardAdapter::getPinAttemptRemaining()
const
722 if (mPinAttemptCounter ==
nullptr) {
723 throw IllegalStateException(
"PIN status has not been checked.");
726 return *mPinAttemptCounter.get();
730CalypsoCardAdapter::setPinAttemptRemaining(
int pinAttemptCounter)
732 mPinAttemptCounter = std::make_shared<int>(pinAttemptCounter);
736CalypsoCardAdapter::setFileHeader(
737 std::uint8_t sfi, std::shared_ptr<FileHeaderAdapter> header)
739 std::shared_ptr<ElementaryFileAdapter> ef
740 = getOrCreateFile(sfi, header->getLid());
741 if (ef->getHeader() ==
nullptr) {
742 ef->setHeader(header);
745 std::dynamic_pointer_cast<FileHeaderAdapter>(ef->getHeader())
746 ->updateMissingInfoFrom(*header.get());
751CalypsoCardAdapter::setContent(
753 std::uint8_t numRecord,
754 const std::vector<uint8_t>& content)
756 std::shared_ptr<ElementaryFileAdapter> ef = getOrCreateFile(sfi, 0);
757 std::dynamic_pointer_cast<FileDataAdapter>(ef->getData())
758 ->setContent(numRecord, content);
762CalypsoCardAdapter::setCounter(
764 std::uint8_t numCounter,
765 const std::vector<uint8_t>& content)
767 std::shared_ptr<ElementaryFileAdapter> ef = getOrCreateFile(sfi, 0);
768 std::dynamic_pointer_cast<FileDataAdapter>(ef->getData())
769 ->setCounter(numCounter, content);
773CalypsoCardAdapter::setContent(
775 std::uint8_t numRecord,
776 const std::vector<uint8_t>& content,
779 std::shared_ptr<ElementaryFileAdapter> ef = getOrCreateFile(sfi, 0);
780 std::dynamic_pointer_cast<FileDataAdapter>(ef->getData())
781 ->setContent(numRecord, content, offset);
785CalypsoCardAdapter::fillContent(
787 std::uint8_t numRecord,
788 const std::vector<uint8_t>& content,
791 std::shared_ptr<ElementaryFileAdapter> ef = getOrCreateFile(sfi, 0);
792 std::dynamic_pointer_cast<FileDataAdapter>(ef->getData())
793 ->fillContent(numRecord, content, offset);
797CalypsoCardAdapter::addCyclicContent(
798 std::uint8_t sfi,
const std::vector<std::uint8_t>& content)
800 std::shared_ptr<ElementaryFileAdapter> ef = getOrCreateFile(sfi, 0);
801 std::dynamic_pointer_cast<FileDataAdapter>(ef->getData())
802 ->addCyclicContent(content);
806CalypsoCardAdapter::backupFiles()
808 copyFiles(mFiles, mFilesBackup);
809 mSvBalanceBackup = mSvBalance;
810 mSvLastTNumBackup = mSvLastTNum;
814CalypsoCardAdapter::restoreFiles()
816 copyFiles(mFilesBackup, mFiles);
817 mSvBalance = mSvBalanceBackup;
818 mSvLastTNum = mSvLastTNumBackup;
822CalypsoCardAdapter::copyFiles(
823 const std::vector<std::shared_ptr<ElementaryFile>>& src,
824 std::vector<std::shared_ptr<ElementaryFile>>& dest)
827 for (
const auto& file : src) {
828 dest.push_back(std::make_shared<ElementaryFileAdapter>(file));
833CalypsoCardAdapter::getPowerOnData()
const
838std::vector<std::uint8_t>
839CalypsoCardAdapter::getSelectApplicationResponse()
const
841 if (mSelectApplicationResponse ==
nullptr) {
845 return mSelectApplicationResponse->getApdu();
849CalypsoCardAdapter::setDfInvalidated(
bool isInvalidated)
851 mIsDfInvalidated = isInvalidated;
855CalypsoCardAdapter::setChallenge(
const std::vector<uint8_t>& challenge)
857 mChallenge = challenge;
861CalypsoCardAdapter::setTraceabilityInformation(
862 const std::vector<uint8_t>& traceabilityInformation)
864 mTraceabilityInformation = traceabilityInformation;
868CalypsoCardAdapter::setCardPublicKey(
869 const std::vector<std::uint8_t>& cardPublicKey)
871 mCardPublicKey = cardPublicKey;
875CalypsoCardAdapter::setCardPublicKeySpi(
876 std::shared_ptr<CardPublicKeySpi> cardPublicKeySpi)
878 mCardPublicKeySpi = cardPublicKeySpi;
881std::shared_ptr<CardPublicKeySpi>
882CalypsoCardAdapter::getCardPublicKeySpi()
const
884 return mCardPublicKeySpi;
888CalypsoCardAdapter::addCardCertificateBytes(
889 const std::vector<std::uint8_t>& cardCertificateBytes,
bool isFirstPart)
892 mCardCertificate.clear();
893 mCardCertificate.reserve(CalypsoCardConstant::CARD_CERTIFICATE_SIZE);
896 const size_t remaining
897 = CalypsoCardConstant::CARD_CERTIFICATE_SIZE - mCardCertificate.size();
898 if (cardCertificateBytes.size() > remaining) {
899 throw IllegalArgumentException(
900 std::string(
"Card certificate is not the correct length. ")
902 + std::to_string(CalypsoCardConstant::CARD_CERTIFICATE_SIZE) +
", "
903 +
"Actual: " + std::to_string(cardCertificateBytes.size()));
906 mCardCertificate.insert(
907 mCardCertificate.end(),
908 cardCertificateBytes.begin(),
909 cardCertificateBytes.end());
913CalypsoCardAdapter::addCaCertificateBytes(
914 const std::vector<std::uint8_t>& caCertificateBytes,
bool isFirstPart)
917 mCaCertificate.reserve(CalypsoCardConstant::CA_CERTIFICATE_SIZE);
920 const size_t remaining
921 = CalypsoCardConstant::CA_CERTIFICATE_SIZE - mCaCertificate.size();
922 if (caCertificateBytes.size() > remaining) {
923 throw IllegalArgumentException(
924 "CA certificate is not the correct length. Expected: "
925 + std::to_string(CalypsoCardConstant::CA_CERTIFICATE_SIZE) +
", "
926 +
"Actual: " + std::to_string(caCertificateBytes.size()));
929 mCaCertificate.insert(
930 mCaCertificate.end(),
931 caCertificateBytes.begin(),
932 caCertificateBytes.end());
936CalypsoCardAdapter::setSvOperationSignature(
937 const std::vector<uint8_t>& svOperationSignature)
939 mSvOperationSignature = svOperationSignature;
942const std::vector<uint8_t>&
943CalypsoCardAdapter::getChallenge()
const
949CalypsoCardAdapter::getSvKvc()
const
954const std::vector<uint8_t>&
955CalypsoCardAdapter::getSvGetHeader()
const
957 if (mSvGetHeader.empty()) {
958 throw IllegalStateException(
"SV Get Header in not available");
964const std::vector<uint8_t>&
965CalypsoCardAdapter::getSvGetData()
const
967 if (mSvGetData.empty()) {
968 throw IllegalStateException(
"SV Get Data is not available");
974const std::vector<uint8_t>&
975CalypsoCardAdapter::getSvOperationSignature()
const
977 return mSvOperationSignature;
981CalypsoCardAdapter::setIsCounterValuePostponed(
bool isCounterValuePostponed)
983 mIsCounterValuePostponed = std::make_shared<bool>(isCounterValuePostponed);
987CalypsoCardAdapter::applyPatchIfNeeded()
989 std::uint64_t startupInfoLong = ByteArrayUtil::extractLong(
990 mStartupInfo, 0,
static_cast<int>(mStartupInfo.size()),
false);
992 if (mProductType == ProductType::PRIME_REVISION_3) {
993 std::vector<std::shared_ptr<CalypsoCardAdapter::Patch>> v;
994 for (
const auto& p : mPatchesRev3) {
996 std::dynamic_pointer_cast<CalypsoCardAdapter::Patch>(p));
999 applyPatchIfNeededForRevision(v, startupInfoLong);
1002 mProductType == ProductType::PRIME_REVISION_2
1003 || mProductType == ProductType::PRIME_REVISION_1) {
1004 mPayloadCapacity = 128;
1006 std::vector<std::shared_ptr<CalypsoCardAdapter::Patch>> v;
1007 for (
const auto& p : mPatchesRev12) {
1009 std::dynamic_pointer_cast<CalypsoCardAdapter::Patch>(p));
1012 applyPatchIfNeededForRevision(v, startupInfoLong);
1017CalypsoCardAdapter::applyPatchIfNeededForRevision(
1018 const std::vector<std::shared_ptr<CalypsoCardAdapter::Patch>>& patches,
1019 const uint64_t startupInfoLong)
1021 for (
const auto& patch : patches) {
1022 if (patch->isApplicableTo(startupInfoLong)) {
1023 patch->apply(shared_from_this());
1029std::shared_ptr<bool>
1030CalypsoCardAdapter::getIsCounterValuePostponed()
const
1032 return mIsCounterValuePostponed;
1036CalypsoCardAdapter::isLegacyCase1()
const
1038 return mIsLegacyCase1;
1042CalypsoCardAdapter::disableExtendedMode()
1044 mIsExtendedModeSupported =
false;
1048CalypsoCardAdapter::getPreOpenWriteAccessLevel()
const
1050 return mPreOpenWriteAccessLevel;
1054CalypsoCardAdapter::setPreOpenWriteAccessLevel(
1055 WriteAccessLevel preOpenWriteAccessLevel)
1057 mPreOpenWriteAccessLevel = preOpenWriteAccessLevel;
1062const std::vector<std::uint8_t>&
1063CalypsoCardAdapter::getPreOpenDataOut()
const
1065 return mPreOpenDataOut;
1069CalypsoCardAdapter::setPreOpenDataOut(
1070 const std::vector<std::uint8_t>& preOpenDataOut)
1072 mPreOpenDataOut = preOpenDataOut;
1077CalypsoCardAdapter::Patch::Patch(
1078 const std::string& startupInfo,
const std::string& mask)
1079: mStartupInfo(HexUtil::toLong(startupInfo))
1080, mMask(HexUtil::toLong(mask))
1085CalypsoCardAdapter::Patch::isApplicableTo(
const uint64_t startupInfo)
const
1087 return mStartupInfo == (startupInfo & mMask);
1090CalypsoCardAdapter::PatchRev3::PatchRev3(
1091 const std::string& startupInfo,
const std::string& mask)
1092: CalypsoCardAdapter::Patch(startupInfo, mask)
1096CalypsoCardAdapter::PatchRev3&
1097CalypsoCardAdapter::PatchRev3::setPayloadCapacity(
const int payloadCapacity)
1099 mPayloadCapacity = std::make_shared<int>(payloadCapacity);
1105CalypsoCardAdapter::PatchRev3::apply(
1106 std::shared_ptr<CalypsoCardAdapter> calypsoCard)
1108 if (mPayloadCapacity !=
nullptr) {
1109 calypsoCard->mPayloadCapacity = *mPayloadCapacity;
1113CalypsoCardAdapter::PatchRev12::PatchRev12(
1114 const std::string& startupInfo,
const std::string& mask)
1115: CalypsoCardAdapter::Patch(startupInfo, mask)
1119CalypsoCardAdapter::PatchRev12&
1120CalypsoCardAdapter::PatchRev12::setLegacyCase1()
1122 mIsLegacyCase1 = std::make_shared<bool>(
true);
1128CalypsoCardAdapter::PatchRev12::apply(
1129 std::shared_ptr<CalypsoCardAdapter> calypsoCard)
1131 if (mIsLegacyCase1 !=
nullptr) {
1132 calypsoCard->mIsLegacyCase1 = *mIsLegacyCase1;
1137operator<<(std::ostream& os,
const CalypsoCardAdapter& cca)
1139 os <<
"CALYPSO_CARD_ADAPTER: {"
1140 <<
"SELECT_APPLICATION_RESPONSE: " << cca.mSelectApplicationResponse
1142 <<
"POWER_ON_DATA: " << cca.mPowerOnData <<
", "
1143 <<
"IS_EXTENDED_MODE_SUPPORTED: " << cca.mIsExtendedModeSupported <<
", "
1144 <<
"IS_RATIFICATION_ON_DESELECT_SUPPORTED: "
1145 << cca.mIsRatificationOnDeselectSupported <<
", "
1146 <<
"IS_SV_FEATURE_AVAILABLE: " << cca.mIsSvFeatureAvailable <<
", "
1147 <<
"IS_PIN_FEATURE_AVAILABLE: " << cca.mIsPinFeatureAvailable <<
", "
1148 <<
"IS_PKI_MODE_SUPPORTED:" << cca.mIsPkiModeSupported <<
", "
1149 <<
"IS_DF_INVALIDATED:" << cca.mIsDfInvalidated <<
", "
1150 <<
"CALYPSO_CARD_CLASS: " << cca.mCalypsoCardClass <<
", "
1151 <<
"CALYPSO_SERIAL_NUMBER: " << cca.mCalypsoSerialNumber <<
", "
1152 <<
"STARTUP_INFO:" << cca.mStartupInfo <<
", "
1153 <<
"PRODUCT_TYPE: " << cca.mProductType <<
", "
1154 <<
"DF_NAME: " << cca.mDfName <<
", "
1155 <<
"MODIFICATIONS_COUNTER_MAX: " << cca.mModificationsCounterMax <<
", "
1156 <<
"IS_MODIFICATION_COUNTER_IN_BYTES: "
1157 << cca.mIsModificationCounterInBytes <<
", "
1158 <<
"DIRECTORY_HEADER: " << cca.mDirectoryHeader <<
", "
1159 <<
"FILES: " << cca.mFiles <<
", "
1160 <<
"FILES_BACKUP: " << cca.mFilesBackup <<
", "
1161 <<
"ID_DF_RATIFIED: " << cca.mIsDfRatified <<
", "
1162 <<
"PIN_ATTEMPT_COUNTER: " << cca.mPinAttemptCounter <<
", "
1163 <<
"SV_BALANCE: " << cca.mSvBalance <<
", "
1164 <<
"SV_LAST_T_NUM: " << cca.mSvLastTNum <<
", "
1165 <<
"IS_HCE: " << cca.mIsHce <<
", "
1166 <<
"TRACEABILITY_INFORMATION: " << cca.mTraceabilityInformation <<
", "
1167 <<
"SV_KVC: " << cca.mSvKvc <<
", "
1168 <<
"SV_GET_HEADER: " << cca.mSvGetHeader <<
", "
1169 <<
"SV_GET_DATA: " << cca.mSvGetData <<
", "
1170 <<
"SV_OPERATION_SIGNATURE: " << cca.mSvOperationSignature <<
", "
1171 <<
"APPLICATION_SUB_TYPE: " << cca.mApplicationSubType <<
", "
1172 <<
"APPLICATION_TYPE: " << cca.mApplicationType <<
", "
1173 <<
"SESSION_MODIFICATION: " << cca.mSessionModification <<
"}";
1179operator<<(std::ostream& os,
const std::shared_ptr<CalypsoCardAdapter> cca)
1181 if (cca ==
nullptr) {
1182 os <<
"CALYPSO_CARD_ADAPTER: null";
std::ostream & operator<<(std::ostream &os, const std::shared_ptr< CalypsoCardAdapter > cca)