20#include "ByteArrayUtil.h"
21#include "IllegalArgumentException.h"
22#include "IllegalStateException.h"
37using namespace keyple::core::util;
38using namespace keyple::core::util::cpp;
39using namespace keyple::core::util::cpp::exception;
43CmdCardOpenSession::SecureSession::SecureSession(
const std::vector<uint8_t>& challengeTransactionCounter,
44 const std::vector<uint8_t>& challengeRandomNumber,
45 const bool previousSessionRatified,
46 const bool manageSecureSessionAuthorized,
47 const std::shared_ptr<uint8_t> kif,
48 const std::shared_ptr<uint8_t> kvc,
49 const std::vector<uint8_t>& originalData,
50 const std::vector<uint8_t>& secureSessionData)
51: mChallengeTransactionCounter(challengeTransactionCounter),
52 mChallengeRandomNumber(challengeRandomNumber),
53 mPreviousSessionRatified(previousSessionRatified),
54 mManageSecureSessionAuthorized(manageSecureSessionAuthorized),
57 mOriginalData(originalData),
58 mSecureSessionData(secureSessionData) {}
60const std::vector<uint8_t>&
61 CmdCardOpenSession::SecureSession::getChallengeTransactionCounter()
const
63 return mChallengeTransactionCounter;
66const std::vector<uint8_t>& CmdCardOpenSession::SecureSession::getChallengeRandomNumber()
const
68 return mChallengeRandomNumber;
71bool CmdCardOpenSession::SecureSession::isPreviousSessionRatified()
const
73 return mPreviousSessionRatified;
76bool CmdCardOpenSession::SecureSession::isManageSecureSessionAuthorized()
const
78 return mManageSecureSessionAuthorized;
81const std::shared_ptr<uint8_t> CmdCardOpenSession::SecureSession::getKIF()
const
86const std::shared_ptr<uint8_t> CmdCardOpenSession::SecureSession::getKVC()
const
91const std::vector<uint8_t>& CmdCardOpenSession::SecureSession::getOriginalData()
const
96const std::vector<uint8_t>& CmdCardOpenSession::SecureSession::getSecureSessionData()
const
98 return mSecureSessionData;
103const std::map<const int, const std::shared_ptr<StatusProperties>>
104 CmdCardOpenSession::STATUS_TABLE = initStatusTable();
106CmdCardOpenSession::CmdCardOpenSession(
const std::shared_ptr<CalypsoCardAdapter> calypsoCard,
107 const uint8_t keyIndex,
108 const std::vector<uint8_t>& samChallenge,
110 const uint8_t recordNumber,
111 const uint8_t recordSize,
112 const bool isExtendedModeAllowed)
114 mRecordSize(recordSize),
115 mIsExtendedModeAllowed(isExtendedModeAllowed)
119 case CalypsoCard::ProductType::PRIME_REVISION_1:
120 createRev10(keyIndex, samChallenge, sfi, recordNumber);
123 case CalypsoCard::ProductType::PRIME_REVISION_2:
124 createRev24(keyIndex, samChallenge, sfi, recordNumber);
127 case CalypsoCard::ProductType::PRIME_REVISION_3:
128 case CalypsoCard::ProductType::LIGHT:
129 case CalypsoCard::ProductType::BASIC:
130 createRev3(keyIndex, samChallenge, sfi, recordNumber);
134 std::stringstream ss;
135 ss <<
"Product type " <<
getCalypsoCard()->getProductType() <<
" isn't supported";
136 throw IllegalArgumentException(ss.str());
141 const std::vector<uint8_t>& samChallenge,
143 const uint8_t recordNumber)
146 mRecordNumber = recordNumber;
148 const uint8_t p1 =
static_cast<uint8_t
>(recordNumber * 8 + keyIndex);
150 std::vector<uint8_t> dataIn;
152 if (mIsExtendedModeAllowed) {
154 p2 =
static_cast<uint8_t
>(sfi * 8 + 2);
155 dataIn = std::vector<uint8_t>(samChallenge.size() + 1);
156 System::arraycopy(samChallenge, 0, dataIn, 1, samChallenge.size());
160 p2 =
static_cast<uint8_t
>(sfi * 8 + 1);
161 dataIn = samChallenge;
169 std::make_shared<ApduRequestAdapter>(
177 std::stringstream extraInfo;
178 extraInfo <<
"KEYINDEX:" << keyIndex <<
", "
179 <<
"SFI:" << sfi <<
"h, "
180 <<
"REC:" << recordNumber;
186 const std::vector<uint8_t>& samChallenge,
188 const uint8_t recordNumber)
190 if (keyIndex == 0x00) {
191 throw IllegalArgumentException(
"Key index can't be zero for rev 2.4!");
195 mRecordNumber = recordNumber;
197 const uint8_t p1 =
static_cast<uint8_t
>(0x80 + recordNumber * 8 + keyIndex);
203 const std::vector<uint8_t>& samChallenge,
205 const uint8_t recordNumber)
207 if (keyIndex == 0x00) {
208 throw IllegalArgumentException(
"Key index can't be zero for rev 1.0!");
212 mRecordNumber = recordNumber;
214 const uint8_t p1 =
static_cast<uint8_t
>(recordNumber * 8 + keyIndex);
220 const std::vector<uint8_t>& samChallenge,
222 const uint8_t recordNumber,
225 const uint8_t p2 =
static_cast<uint8_t
>(sfi * 8);
232 std::make_shared<ApduRequestAdapter>(
240 std::stringstream extraInfo;
241 extraInfo <<
"KEYINDEX:" << keyIndex <<
", "
242 <<
"SFI:" << sfi <<
"h, "
243 <<
"REC:" << recordNumber;
260 return mRecordNumber;
271 case CalypsoCard::ProductType::PRIME_REVISION_1:
275 case CalypsoCard::ProductType::PRIME_REVISION_2:
284 getCalypsoCard()->setDfRatified(mSecureSession->isPreviousSessionRatified());
288 ByteArrayUtil::extractInt(mSecureSession->getChallengeTransactionCounter(), 0, 3,
false));
290 if (mSecureSession->getOriginalData().size() > 0) {
292 getCalypsoCard()->setContent(mSfi, mRecordNumber, mSecureSession->getOriginalData());
298 bool previousSessionRatified;
299 bool manageSecureSessionAuthorized;
303 if (mIsExtendedModeAllowed) {
305 previousSessionRatified = (apduResponseData[8] & 0x01) == 0x00;
306 manageSecureSessionAuthorized = (apduResponseData[8] & 0x02) == 0x02;
309 previousSessionRatified = apduResponseData[4] == 0x00;
310 manageSecureSessionAuthorized =
false;
313 const auto kif = std::make_shared<uint8_t>(apduResponseData[5 + offset]);
314 const auto kvc = std::make_shared<uint8_t>(apduResponseData[6 + offset]);
315 const int dataLength = apduResponseData[7 + offset];
317 if (dataLength !=
static_cast<int>(apduResponseData.size() - 8 - offset)) {
318 throw IllegalStateException(
"Inconsistent response length for Open Secure Session.");
321 const std::vector<uint8_t> data =
322 Arrays::copyOfRange(apduResponseData, 8 + offset, 8 + offset + dataLength);
324 mSecureSession = std::shared_ptr<SecureSession>(
326 Arrays::copyOfRange(apduResponseData, 0, 3),
327 Arrays::copyOfRange(apduResponseData, 3, 4 + offset),
328 previousSessionRatified,
329 manageSecureSessionAuthorized,
338 bool previousSessionRatified;
339 std::vector<uint8_t> data;
341 switch (apduResponseData.size()) {
343 previousSessionRatified =
true;
344 data = std::vector<uint8_t>(0);
347 if (mRecordSize != 29) {
348 throw IllegalStateException(
"Inconsistent response length for Open Secure Session.");
350 previousSessionRatified =
true;
351 data = Arrays::copyOfRange(apduResponseData, 5, 34);
354 previousSessionRatified =
false;
355 data = std::vector<uint8_t>(0);
358 if (mRecordSize != 29) {
359 throw IllegalStateException(
"Inconsistent response length for Open Secure Session.");
361 previousSessionRatified =
false;
362 data = Arrays::copyOfRange(apduResponseData, 7, 36);
365 throw IllegalStateException(
"Bad response length to Open Secure Session: " +
366 std::to_string(apduResponseData.size()));
369 const auto kvc = std::make_shared<uint8_t>(apduResponseData[0]);
371 mSecureSession = std::shared_ptr<SecureSession>(
373 Arrays::copyOfRange(apduResponseData, 1, 4),
374 Arrays::copyOfRange(apduResponseData, 4, 5),
375 previousSessionRatified,
385 bool previousSessionRatified;
386 std::vector<uint8_t> data;
388 switch (apduResponseData.size()) {
390 previousSessionRatified =
true;
391 data = std::vector<uint8_t>(0);
394 if (mRecordSize != 29) {
395 throw IllegalStateException(
"Inconsistent response length for Open Secure Session.");
397 previousSessionRatified =
true;
398 data = Arrays::copyOfRange(apduResponseData, 4, 33);
401 previousSessionRatified =
false;
402 data = std::vector<uint8_t>(0);
405 if (mRecordSize != 29) {
406 throw IllegalStateException(
"Inconsistent response length for Open Secure Session.");
408 previousSessionRatified =
false;
409 data = Arrays::copyOfRange(apduResponseData, 6, 35);
412 throw IllegalStateException(
"Bad response length to Open Secure Session: " +
413 std::to_string(apduResponseData.size()));
417 mSecureSession = std::shared_ptr<SecureSession>(
419 Arrays::copyOfRange(apduResponseData, 0, 3),
420 Arrays::copyOfRange(apduResponseData, 3, 4),
421 previousSessionRatified,
431 return mSecureSession->getChallengeRandomNumber();
436 return mSecureSession->isManageSecureSessionAuthorized();
441 return mSecureSession->getKIF();
446 return mSecureSession->getKVC();
449const std::map<const int, const std::shared_ptr<StatusProperties>>
450 CmdCardOpenSession::initStatusTable()
452 std::map<const int, const std::shared_ptr<StatusProperties>> m =
456 std::make_shared<StatusProperties>(
"Lc value not supported.",
459 std::make_shared<StatusProperties>(
"Transaction Counter is 0",
460 typeid(CardTerminatedException))});
462 std::make_shared<StatusProperties>(
"Command forbidden (read requested and current " \
463 "EF is a Binary file).",
464 typeid(CardDataAccessException))});
466 std::make_shared<StatusProperties>(
"Security conditions not fulfilled (PIN code " \
467 "not presented, AES key forbidding the " \
468 "compatibility mode, encryption required).",
469 typeid(CardSecurityContextException))});
471 std::make_shared<StatusProperties>(
"Access forbidden (Never access mode, Session " \
473 typeid(CardAccessForbiddenException))});
475 std::make_shared<StatusProperties>(
"Command not allowed (read requested and no " \
477 typeid(CardDataAccessException))});
479 std::make_shared<StatusProperties>(
"Wrong key index.",
480 typeid(CardIllegalParameterException))});
482 std::make_shared<StatusProperties>(
"File not found.",
483 typeid(CardDataAccessException))});
485 std::make_shared<StatusProperties>(
"Record not found (record index is above NumRec).",
486 typeid(CardDataAccessException))});
488 std::make_shared<StatusProperties>(
"P1 or P2 value not supported (key index " \
489 "incorrect, wrong P2).",
490 typeid(CardIllegalParameterException))});
492 std::make_shared<StatusProperties>(
"Correct execution (ISO7816 T=0).",
498const std::map<const int, const std::shared_ptr<StatusProperties>>&
static const std::map< const int, const std::shared_ptr< StatusProperties > > STATUS_TABLE
virtual void addSubName(const std::string &subName) final
virtual const std::shared_ptr< ApduResponseApi > getApduResponse() const final
virtual void setApduRequest(const std::shared_ptr< ApduRequestAdapter > apduRequest) final
void parseApduResponse(const std::shared_ptr< ApduResponseApi > apduResponse) override
std::shared_ptr< CalypsoCardAdapter > getCalypsoCard() const
static const CalypsoCardClass LEGACY
static const CalypsoCardClass ISO
static const CalypsoCardCommand OPEN_SESSION
void createRev24(const uint8_t keyIndex, const std::vector< uint8_t > &samChallenge, const uint8_t sfi, const uint8_t recordNumber)
bool isManageSecureSessionAuthorized() const
void createRev3(const uint8_t keyIndex, const std::vector< uint8_t > &samChallenge, const uint8_t sfi, const uint8_t recordNumber)
const std::vector< uint8_t > & getCardChallenge() const
const std::map< const int, const std::shared_ptr< StatusProperties > > & getStatusTable() const override
void parseRev24(const std::vector< uint8_t > &apduResponseData)
void buildLegacyApduRequest(const uint8_t keyIndex, const std::vector< uint8_t > &samChallenge, const uint8_t sfi, const uint8_t recordNumber, const uint8_t p1)
const std::shared_ptr< uint8_t > getSelectedKif() const
void parseApduResponse(const std::shared_ptr< ApduResponseApi > apduResponse) override
bool isSessionBufferUsed() const override
const std::shared_ptr< uint8_t > getSelectedKvc() const
uint8_t getRecordNumber() const
void parseRev3(const std::vector< uint8_t > &apduResponseData)
void createRev10(const uint8_t keyIndex, const std::vector< uint8_t > &samChallenge, const uint8_t sfi, const uint8_t recordNumber)
void parseRev10(const std::vector< uint8_t > &apduResponseData)