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();
107 const uint8_t keyIndex,
108 const std::vector<uint8_t>& samChallenge,
110 const uint8_t recordNumber,
111 const bool isExtendedModeAllowed)
113 mProductType(productType),
114 mIsExtendedModeAllowed(isExtendedModeAllowed)
116 switch (productType) {
117 case CalypsoCard::ProductType::PRIME_REVISION_1:
118 createRev10(keyIndex, samChallenge, sfi, recordNumber);
120 case CalypsoCard::ProductType::PRIME_REVISION_2:
121 createRev24(keyIndex, samChallenge, sfi, recordNumber);
123 case CalypsoCard::ProductType::PRIME_REVISION_3:
124 case CalypsoCard::ProductType::LIGHT:
125 case CalypsoCard::ProductType::BASIC:
126 createRev3(keyIndex, samChallenge, sfi, recordNumber);
129 std::stringstream ss;
130 ss <<
"Product type " << productType <<
" isn't supported";
131 throw IllegalArgumentException(ss.str());
136 const std::vector<uint8_t>& samChallenge,
138 const uint8_t recordNumber)
141 mRecordNumber = recordNumber;
143 const uint8_t p1 =
static_cast<uint8_t
>(recordNumber * 8 + keyIndex);
145 std::vector<uint8_t> dataIn;
147 if (mIsExtendedModeAllowed) {
148 p2 =
static_cast<uint8_t
>(sfi * 8 + 2);
149 dataIn = std::vector<uint8_t>(samChallenge.size() + 1);
150 System::arraycopy(samChallenge, 0, dataIn, 1, samChallenge.size());
152 p2 =
static_cast<uint8_t
>(sfi * 8 + 1);
153 dataIn = samChallenge;
161 std::make_shared<ApduRequestAdapter>(
169 std::stringstream extraInfo;
170 extraInfo <<
"KEYINDEX:" << keyIndex <<
", "
171 <<
"SFI:" << sfi <<
"h, "
172 <<
"REC:" << recordNumber;
178 const std::vector<uint8_t>& samChallenge,
180 const uint8_t recordNumber)
182 if (keyIndex == 0x00) {
183 throw IllegalArgumentException(
"Key index can't be zero for rev 2.4!");
187 mRecordNumber = recordNumber;
189 const uint8_t p1 =
static_cast<uint8_t
>(0x80 + recordNumber * 8 + keyIndex);
195 const std::vector<uint8_t>& samChallenge,
197 const uint8_t recordNumber)
199 if (keyIndex == 0x00) {
200 throw IllegalArgumentException(
"Key index can't be zero for rev 1.0!");
204 mRecordNumber = recordNumber;
206 const uint8_t p1 =
static_cast<uint8_t
>(recordNumber * 8 + keyIndex);
212 const std::vector<uint8_t>& samChallenge,
214 const uint8_t recordNumber,
217 const uint8_t p2 =
static_cast<uint8_t
>(sfi * 8);
224 std::make_shared<ApduRequestAdapter>(
232 std::stringstream extraInfo;
233 extraInfo <<
"KEYINDEX:" << keyIndex <<
", "
234 <<
"SFI:" << sfi <<
"h, "
235 <<
"REC:" << recordNumber;
252 return mRecordNumber;
256 const std::shared_ptr<ApduResponseApi> apduResponse)
261 if (dataOut.size() > 0) {
262 switch (mProductType) {
263 case CalypsoCard::ProductType::PRIME_REVISION_1:
266 case CalypsoCard::ProductType::PRIME_REVISION_2:
279 bool previousSessionRatified;
280 bool manageSecureSessionAuthorized;
284 if (mIsExtendedModeAllowed) {
286 previousSessionRatified = (apduResponseData[8] & 0x01) == 0x00;
287 manageSecureSessionAuthorized = (apduResponseData[8] & 0x02) == 0x02;
290 previousSessionRatified = apduResponseData[4] == 0x00;
291 manageSecureSessionAuthorized =
false;
294 const auto kif = std::make_shared<uint8_t>(apduResponseData[5 + offset]);
295 const auto kvc = std::make_shared<uint8_t>(apduResponseData[6 + offset]);
296 const int dataLength = apduResponseData[7 + offset];
297 const std::vector<uint8_t> data =
298 Arrays::copyOfRange(apduResponseData, 8 + offset, 8 + offset + dataLength);
300 mSecureSession = std::shared_ptr<SecureSession>(
302 Arrays::copyOfRange(apduResponseData, 0, 3),
303 Arrays::copyOfRange(apduResponseData, 3, 4 + offset),
304 previousSessionRatified,
305 manageSecureSessionAuthorized,
314 bool previousSessionRatified;
315 std::vector<uint8_t> data;
317 switch (apduResponseData.size()) {
319 previousSessionRatified =
true;
320 data = std::vector<uint8_t>(0);
323 previousSessionRatified =
true;
324 data = Arrays::copyOfRange(apduResponseData, 5, 34);
327 previousSessionRatified =
false;
328 data = std::vector<uint8_t>(0);
331 previousSessionRatified =
false;
332 data = Arrays::copyOfRange(apduResponseData, 7, 36);
335 throw IllegalStateException(
"Bad response length to Open Secure Session: " +
336 std::to_string(apduResponseData.size()));
339 const auto kvc = std::make_shared<uint8_t>(apduResponseData[0]);
341 mSecureSession = std::shared_ptr<SecureSession>(
343 Arrays::copyOfRange(apduResponseData, 1, 4),
344 Arrays::copyOfRange(apduResponseData, 4, 5),
345 previousSessionRatified,
355 bool previousSessionRatified;
356 std::vector<uint8_t> data;
358 switch (apduResponseData.size()) {
360 previousSessionRatified =
true;
361 data = std::vector<uint8_t>(0);
364 previousSessionRatified =
true;
365 data = Arrays::copyOfRange(apduResponseData, 4, 33);
368 previousSessionRatified =
false;
369 data = std::vector<uint8_t>(0);
372 previousSessionRatified =
false;
373 data = Arrays::copyOfRange(apduResponseData, 6, 35);
376 throw IllegalStateException(
"Bad response length to Open Secure Session: " +
377 std::to_string(apduResponseData.size()));
381 mSecureSession = std::shared_ptr<SecureSession>(
383 Arrays::copyOfRange(apduResponseData, 0, 3),
384 Arrays::copyOfRange(apduResponseData, 3, 4),
385 previousSessionRatified,
395 return mSecureSession->getChallengeRandomNumber();
400 return ByteArrayUtil::extractInt(mSecureSession->getChallengeTransactionCounter(), 0, 3,
false);
405 return mSecureSession->isPreviousSessionRatified();
410 return mSecureSession->isManageSecureSessionAuthorized();
415 return mSecureSession->getKIF();
420 return mSecureSession->getKVC();
425 return mSecureSession->getOriginalData();
428const std::map<const int, const std::shared_ptr<StatusProperties>>
429 CmdCardOpenSession::initStatusTable()
431 std::map<const int, const std::shared_ptr<StatusProperties>> m =
435 std::make_shared<StatusProperties>(
"Lc value not supported.",
438 std::make_shared<StatusProperties>(
"Transaction Counter is 0",
439 typeid(CardTerminatedException))});
441 std::make_shared<StatusProperties>(
"Command forbidden (read requested and current " \
442 "EF is a Binary file).",
443 typeid(CardDataAccessException))});
445 std::make_shared<StatusProperties>(
"Security conditions not fulfilled (PIN code " \
446 "not presented, AES key forbidding the " \
447 "compatibility mode, encryption required).",
448 typeid(CardSecurityContextException))});
450 std::make_shared<StatusProperties>(
"Access forbidden (Never access mode, Session " \
452 typeid(CardAccessForbiddenException))});
454 std::make_shared<StatusProperties>(
"Command not allowed (read requested and no " \
456 typeid(CardDataAccessException))});
458 std::make_shared<StatusProperties>(
"Wrong key index.",
459 typeid(CardIllegalParameterException))});
461 std::make_shared<StatusProperties>(
"File not found.",
462 typeid(CardDataAccessException))});
464 std::make_shared<StatusProperties>(
"Record not found (record index is above NumRec).",
465 typeid(CardDataAccessException))});
467 std::make_shared<StatusProperties>(
"P1 or P2 value not supported (key index " \
468 "incorrect, wrong P2).",
469 typeid(CardIllegalParameterException))});
471 std::make_shared<StatusProperties>(
"Correct execution (ISO7816 T=0).",
477const 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
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)
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)
CalypsoSam::ProductType ProductType