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<CalypsoCard> calypsoCard,
107 const uint8_t debitKeyIndex,
108 const std::vector<uint8_t> sessionTerminalChallenge,
110 const uint8_t recordNumber)
112 mCalypsoCard(calypsoCard)
114 switch (calypsoCard->getProductType()) {
115 case CalypsoCard::ProductType::PRIME_REVISION_1:
116 createRev10(debitKeyIndex, sessionTerminalChallenge, sfi, recordNumber);
118 case CalypsoCard::ProductType::PRIME_REVISION_2:
119 createRev24(debitKeyIndex, sessionTerminalChallenge, sfi, recordNumber);
121 case CalypsoCard::ProductType::PRIME_REVISION_3:
122 case CalypsoCard::ProductType::LIGHT:
123 case CalypsoCard::ProductType::BASIC:
124 createRev3(debitKeyIndex, sessionTerminalChallenge, sfi, recordNumber, calypsoCard);
127 std::stringstream ss;
128 ss <<
"Product type " << calypsoCard->getProductType() <<
" isn't supported";
129 throw IllegalArgumentException(ss.str());
134 const std::vector<uint8_t>& samChallenge,
136 const uint8_t recordNumber,
137 const std::shared_ptr<CalypsoCard> calypsoCard)
140 mRecordNumber = recordNumber;
142 const uint8_t p1 =
static_cast<uint8_t
>(recordNumber * 8 + keyIndex);
144 std::vector<uint8_t> dataIn;
147 if (!calypsoCard->isExtendedModeSupported()) {
148 p2 =
static_cast<uint8_t
>(sfi * 8 + 1);
149 dataIn = samChallenge;
151 p2 =
static_cast<uint8_t
>(sfi * 8 + 2);
152 dataIn = std::vector<uint8_t>(samChallenge.size() + 1);
154 System::arraycopy(samChallenge, 0, dataIn, 1, samChallenge.size());
161 const uint8_t le = 0;
164 std::make_shared<ApduRequestAdapter>(
172 std::stringstream extraInfo;
173 extraInfo <<
"KEYINDEX:" << keyIndex <<
", "
174 <<
"SFI:" << sfi <<
"h, "
175 <<
"REC:" << recordNumber;
181 const std::vector<uint8_t>& samChallenge,
183 const uint8_t recordNumber)
185 if (keyIndex == 0x00) {
186 throw IllegalArgumentException(
"Key index can't be zero for rev 2.4!");
190 mRecordNumber = recordNumber;
192 const uint8_t p1 =
static_cast<uint8_t
>(0x80 + recordNumber * 8 + keyIndex);
198 const std::vector<uint8_t>& samChallenge,
200 const uint8_t recordNumber)
202 if (keyIndex == 0x00) {
203 throw IllegalArgumentException(
"Key index can't be zero for rev 1.0!");
207 mRecordNumber = recordNumber;
209 const uint8_t p1 =
static_cast<uint8_t
>(recordNumber * 8 + keyIndex);
215 const std::vector<uint8_t>& samChallenge,
217 const uint8_t recordNumber,
220 const uint8_t p2 =
static_cast<uint8_t
>(sfi * 8);
226 const uint8_t le = 0;
229 std::make_shared<ApduRequestAdapter>(
237 std::stringstream extraInfo;
238 extraInfo <<
"KEYINDEX:" << keyIndex <<
", "
239 <<
"SFI:" << sfi <<
"h, "
240 <<
"REC:" << recordNumber;
257 return mRecordNumber;
261 const std::shared_ptr<ApduResponseApi> apduResponse)
266 if (dataOut.size() > 0) {
267 switch (mCalypsoCard->getProductType()) {
268 case CalypsoCard::ProductType::PRIME_REVISION_1:
271 case CalypsoCard::ProductType::PRIME_REVISION_2:
284 bool previousSessionRatified;
285 bool manageSecureSessionAuthorized;
289 if (!mCalypsoCard->isExtendedModeSupported()) {
291 previousSessionRatified = apduResponseData[4] == 0x00;
292 manageSecureSessionAuthorized =
false;
295 previousSessionRatified = (apduResponseData[8] & 0x01) == 0x00;
296 manageSecureSessionAuthorized = (apduResponseData[8] & 0x02) == 0x02;
299 const auto kif = std::make_shared<uint8_t>(apduResponseData[5 + offset]);
300 const auto kvc = std::make_shared<uint8_t>(apduResponseData[6 + offset]);
301 const int dataLength = apduResponseData[7 + offset];
302 const std::vector<uint8_t> data =
303 Arrays::copyOfRange(apduResponseData, 8 + offset, 8 + offset + dataLength);
305 mSecureSession = std::shared_ptr<SecureSession>(
307 Arrays::copyOfRange(apduResponseData, 0, 3),
308 Arrays::copyOfRange(apduResponseData, 3, 4 + offset),
309 previousSessionRatified,
310 manageSecureSessionAuthorized,
319 bool previousSessionRatified;
320 std::vector<uint8_t> data;
322 switch (apduResponseData.size()) {
324 previousSessionRatified =
true;
325 data = std::vector<uint8_t>(0);
328 previousSessionRatified =
true;
329 data = Arrays::copyOfRange(apduResponseData, 5, 34);
332 previousSessionRatified =
false;
333 data = std::vector<uint8_t>(0);
336 previousSessionRatified =
false;
337 data = Arrays::copyOfRange(apduResponseData, 7, 36);
340 throw IllegalStateException(
"Bad response length to Open Secure Session: " +
341 std::to_string(apduResponseData.size()));
344 const auto kvc = std::make_shared<uint8_t>(apduResponseData[0]);
346 mSecureSession = std::shared_ptr<SecureSession>(
348 Arrays::copyOfRange(apduResponseData, 1, 4),
349 Arrays::copyOfRange(apduResponseData, 4, 5),
350 previousSessionRatified,
360 bool previousSessionRatified;
361 std::vector<uint8_t> data;
363 switch (apduResponseData.size()) {
365 previousSessionRatified =
true;
366 data = std::vector<uint8_t>(0);
369 previousSessionRatified =
true;
370 data = Arrays::copyOfRange(apduResponseData, 4, 33);
373 previousSessionRatified =
false;
374 data = std::vector<uint8_t>(0);
377 previousSessionRatified =
false;
378 data = Arrays::copyOfRange(apduResponseData, 6, 35);
381 throw IllegalStateException(
"Bad response length to Open Secure Session: " +
382 std::to_string(apduResponseData.size()));
386 mSecureSession = std::shared_ptr<SecureSession>(
388 Arrays::copyOfRange(apduResponseData, 0, 3),
389 Arrays::copyOfRange(apduResponseData, 3, 4),
390 previousSessionRatified,
400 return mSecureSession->getChallengeRandomNumber();
405 return ByteArrayUtil::threeBytesToInt(mSecureSession->getChallengeTransactionCounter(), 0);
410 return mSecureSession->isPreviousSessionRatified();
415 return mSecureSession->isManageSecureSessionAuthorized();
420 return mSecureSession->getKIF();
425 return mSecureSession->getKVC();
430 return mSecureSession->getOriginalData();
433const std::map<const int, const std::shared_ptr<StatusProperties>>
434 CmdCardOpenSession::initStatusTable()
436 std::map<const int, const std::shared_ptr<StatusProperties>> m =
440 std::make_shared<StatusProperties>(
"Lc value not supported.",
443 std::make_shared<StatusProperties>(
"Transaction Counter is 0",
444 typeid(CardTerminatedException))});
446 std::make_shared<StatusProperties>(
"Command forbidden (read requested and current " \
447 "EF is a Binary file).",
448 typeid(CardDataAccessException))});
450 std::make_shared<StatusProperties>(
"Security conditions not fulfilled (PIN code " \
451 "not presented, AES key forbidding the " \
452 "compatibility mode, encryption required).",
453 typeid(CardSecurityContextException))});
455 std::make_shared<StatusProperties>(
"Access forbidden (Never access mode, Session " \
457 typeid(CardAccessForbiddenException))});
459 std::make_shared<StatusProperties>(
"Command not allowed (read requested and no " \
461 typeid(CardDataAccessException))});
463 std::make_shared<StatusProperties>(
"Wrong key index.",
464 typeid(CardIllegalParameterException))});
466 std::make_shared<StatusProperties>(
"File not found.",
467 typeid(CardDataAccessException))});
469 std::make_shared<StatusProperties>(
"Record not found (record index is above NumRec).",
470 typeid(CardDataAccessException))});
472 std::make_shared<StatusProperties>(
"P1 or P2 value not supported (key index " \
473 "incorrect, wrong P2).",
474 typeid(CardIllegalParameterException))});
476 std::make_shared<StatusProperties>(
"Correct execution (ISO7816 T=0).",
482const 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
AbstractCardCommand & setApduResponse(const std::shared_ptr< ApduResponseApi > apduResponse) override
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)
const std::vector< uint8_t > & getRecordDataRead() const
bool isManageSecureSessionAuthorized() const
const std::vector< uint8_t > & getCardChallenge() const
void createRev3(const uint8_t keyIndex, const std::vector< uint8_t > &samChallenge, const uint8_t sfi, const uint8_t recordNumber, const std::shared_ptr< CalypsoCard > calypsoCard)
const std::map< const int, const std::shared_ptr< StatusProperties > > & getStatusTable() const override
void parseRev24(const std::vector< uint8_t > &apduResponseData)
CmdCardOpenSession & setApduResponse(const std::shared_ptr< ApduResponseApi > apduResponse) override
int getTransactionCounterValue() const
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
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)