26#include "IllegalStateException.h"
34using namespace keyple::core::util;
35using namespace keyple::core::util::cpp;
36using namespace keyple::core::util::cpp::exception;
41 const std::shared_ptr<CalypsoCardAdapter> targetCard,
42 const std::shared_ptr<CardSecuritySettingAdapter> securitySetting,
43 const std::vector<std::vector<uint8_t>>& transactionAuditData)
48 targetCard->getCalypsoSerialNumberFull(),
49 transactionAuditData),
50 mControlSam(securitySetting ? securitySetting->getControlSam() : nullptr),
51 mTargetCard(targetCard),
52 mCardSecuritySetting(securitySetting) {}
55 const WriteAccessLevel writeAccessLevel,
56 const std::shared_ptr<uint8_t> kvc)
const
62 return mCardSecuritySetting->getDefaultKvc(writeAccessLevel);
66 const WriteAccessLevel writeAccessLevel,
67 const std::shared_ptr<uint8_t> kif,
68 const std::shared_ptr<uint8_t> kvc)
const
71 if ((kif !=
nullptr && *kif != 0xFF) || (kvc ==
nullptr)) {
76 std::shared_ptr<uint8_t> result = mCardSecuritySetting->getKif(writeAccessLevel, *kvc);
77 if (result ==
nullptr) {
78 result = mCardSecuritySetting->getDefaultKif(writeAccessLevel);
94 mDigestManager !=
nullptr &&
95 !mDigestManager->mIsDigestInitDone) {
98 std::vector<std::shared_ptr<AbstractApduCommand>> samCommands =
getSamCommands();
100 mDigestManager->prepareDigestInit();
111 const auto cmd = std::make_shared<CmdSamGetChallenge>(mControlSam,
112 mTargetCard->isExtendedModeSupported() ?
123 getSamCommands().push_back(std::make_shared<CmdSamGiveRandom>(mControlSam,
124 mTargetCard->getCardChallenge()));
127const std::shared_ptr<CmdSamCardGenerateKey>
129 const uint8_t cipheringKvc,
130 const uint8_t sourceKif,
131 const uint8_t sourceKvc)
133 const auto cmd = std::make_shared<CmdSamCardGenerateKey>(mControlSam,
143const std::shared_ptr<CmdSamCardCipherPin>
145 const std::vector<uint8_t>& currentPin,
146 const std::vector<uint8_t>& newPin)
148 uint8_t pinCipheringKif;
149 uint8_t pinCipheringKvc;
151 if (mDigestManager !=
nullptr && mDigestManager->mSessionKif != 0) {
153 pinCipheringKif = mDigestManager->mSessionKif;
154 pinCipheringKvc = mDigestManager->mSessionKvc;
158 if (newPin.empty()) {
160 if (mCardSecuritySetting->getPinVerificationCipheringKif() ==
nullptr ||
161 mCardSecuritySetting->getPinVerificationCipheringKvc() ==
nullptr) {
162 throw IllegalStateException(
"No KIF or KVC defined for the PIN verification " \
166 pinCipheringKif = *mCardSecuritySetting->getPinVerificationCipheringKif();
167 pinCipheringKvc = *mCardSecuritySetting->getPinVerificationCipheringKvc();
170 if (mCardSecuritySetting->getPinModificationCipheringKif() ==
nullptr ||
171 mCardSecuritySetting->getPinModificationCipheringKvc() ==
nullptr) {
172 throw IllegalStateException(
"No KIF or KVC defined for the PIN modification " \
176 pinCipheringKif = *mCardSecuritySetting->getPinModificationCipheringKif();
177 pinCipheringKvc = *mCardSecuritySetting->getPinModificationCipheringKvc();
181 const auto cmd = std::make_shared<CmdSamCardCipherPin>(mControlSam,
191const std::shared_ptr<CmdSamSvPrepareLoad>
193 const std::vector<uint8_t>& svGetHeader,
194 const std::vector<uint8_t>& svGetData,
195 const std::shared_ptr<CmdCardSvReload> cmdCardSvReload)
198 const auto cmd = std::make_shared<CmdSamSvPrepareLoad>(mControlSam,
201 cmdCardSvReload->getSvReloadData());
207const std::shared_ptr<CmdSamSvPrepareDebitOrUndebit>
209 const bool isDebitCommand,
210 const std::vector<uint8_t>& svGetHeader,
211 const std::vector<uint8_t>& svGetData,
212 const std::shared_ptr<CmdCardSvDebitOrUndebit> cmdCardSvDebitOrUndebit)
215 const auto cmd = std::make_shared<CmdSamSvPrepareDebitOrUndebit>(
220 cmdCardSvDebitOrUndebit->getSvDebitOrUndebitData());
227 const std::vector<uint8_t>& svOperationData)
229 getSamCommands().push_back(std::make_shared<CmdSamSvCheck>(mControlSam,
234 const std::vector<uint8_t>& openSecureSessionDataOut,
237 const bool isSessionEncrypted,
238 const bool isVerificationMode)
240 mDigestManager = std::make_shared<DigestManager>(
this,
241 openSecureSessionDataOut,
249 const std::vector<std::shared_ptr<ApduRequestSpi>>& requests,
250 const std::vector<std::shared_ptr<ApduResponseApi>>& responses,
251 const int startIndex)
253 mDigestManager->updateSession(requests, responses, startIndex);
256const std::shared_ptr<CmdSamDigestClose>
259 mDigestManager->prepareCommands();
260 mDigestManager =
nullptr;
262 return std::dynamic_pointer_cast<CmdSamDigestClose>(
267 const std::vector<uint8_t>& cardSignatureLo)
269 getSamCommands().push_back(std::make_shared<CmdSamDigestAuthenticate>(
276CardControlSamTransactionManagerAdapter::DigestManager::DigestManager(
278 const std::vector<uint8_t>& openSecureSessionDataOut,
281 const bool isSessionEncrypted,
282 const bool isVerificationMode)
285 mOpenSecureSessionDataOut(openSecureSessionDataOut),
286 mIsSessionEncrypted(isSessionEncrypted),
287 mIsVerificationMode(isVerificationMode),
290void CardControlSamTransactionManagerAdapter::DigestManager::updateSession(
291 const std::vector<std::shared_ptr<ApduRequestSpi>>& requests,
292 const std::vector<std::shared_ptr<ApduResponseApi>>& responses,
293 const int startIndex)
295 for (
int i = startIndex; i < static_cast<int>(requests.size()); i++) {
301 const std::shared_ptr<ApduRequestSpi> request = requests[i];
302 mCardApdus.push_back(ApduUtil::isCase4(request->getApdu()) ?
303 Arrays::copyOfRange(request->getApdu(),
305 request->getApdu().size() - 1) :
308 const std::shared_ptr<ApduResponseApi> response = responses[i];
309 mCardApdus.push_back(response->getApdu());
313void CardControlSamTransactionManagerAdapter::DigestManager::prepareCommands()
316 if (!mIsDigestInitDone) {
322 prepareDigestUpdate();
326 prepareDigestClose();
329void CardControlSamTransactionManagerAdapter::DigestManager::prepareDigestInit()
332 mParent->getSamCommands().push_back(std::make_shared<CmdSamDigestInit>(
333 mParent->mControlSam,
335 mParent->mTargetCard->isExtendedModeSupported(),
338 mOpenSecureSessionDataOut));
340 mIsDigestInitDone =
true;
343void CardControlSamTransactionManagerAdapter::DigestManager::prepareDigestUpdate()
345 if (mCardApdus.empty()) {
350 if (mParent->mControlSam->getProductType() == CalypsoSam::ProductType::SAM_C1) {
356 std::vector<std::vector<uint8_t>> digestDataList;
357 std::vector<uint8_t> buffer(255);
360 for (
const auto& cardApdu : mCardApdus) {
362 if (
static_cast<int>(i + cardApdu.size()) > 254) {
365 digestDataList.push_back(Arrays::copyOf(buffer, i));
370 buffer[i++] =
static_cast<uint8_t
>(cardApdu.size());
371 System::arraycopy(cardApdu, 0, buffer, i, cardApdu.size());
372 i += cardApdu.size();
376 digestDataList.push_back(Arrays::copyOf(buffer, i));
379 for (
const auto& dataIn : digestDataList) {
381 mParent->getSamCommands().push_back(
382 std::make_shared<CmdSamDigestUpdateMultiple>(mParent->mControlSam,
389 for (
const auto& cardApdu : mCardApdus) {
391 mParent->getSamCommands().push_back(
392 std::make_shared<CmdSamDigestUpdate>(mParent->mControlSam,
399void CardControlSamTransactionManagerAdapter::DigestManager::prepareDigestClose()
402 mParent->getSamCommands().push_back(std::make_shared<CmdSamDigestClose>(
403 mParent->mControlSam,
404 mParent->mTargetCard->isExtendedModeSupported() ?
const std::shared_ptr< CmdSamSvPrepareDebitOrUndebit > prepareSvPrepareDebitOrUndebit(const bool isDebitCommand, const std::vector< uint8_t > &svGetHeader, const std::vector< uint8_t > &svGetData, const std::shared_ptr< CmdCardSvDebitOrUndebit > cmdCardSvDebitOrUndebit)
void prepareDigestAuthenticate(const std::vector< uint8_t > &cardSignatureLo)
const std::shared_ptr< CmdSamSvPrepareLoad > prepareSvPrepareLoad(const std::vector< uint8_t > &svGetHeader, const std::vector< uint8_t > &svGetData, const std::shared_ptr< CmdCardSvReload > cmdCardSvReload)
void updateSession(const std::vector< std::shared_ptr< ApduRequestSpi > > &requests, const std::vector< std::shared_ptr< ApduResponseApi > > &responses, const int startIndex)
const std::shared_ptr< CmdSamDigestClose > prepareSessionClosing()
const std::shared_ptr< CmdSamCardGenerateKey > prepareCardGenerateKey(const uint8_t cipheringKif, const uint8_t cipheringKvc, const uint8_t sourceKif, const uint8_t sourceKvc)
CardControlSamTransactionManagerAdapter(const std::shared_ptr< CalypsoCardAdapter > targetCard, const std::shared_ptr< CardSecuritySettingAdapter > securitySetting, const std::vector< std::vector< uint8_t > > &transactionAuditData)
std::shared_ptr< CmdSamGetChallenge > prepareGetChallenge()
void prepareSvCheck(const std::vector< uint8_t > &svOperationData)
std::shared_ptr< uint8_t > computeKif(const WriteAccessLevel writeAccessLevel, const std::shared_ptr< uint8_t > kif, const std::shared_ptr< uint8_t > kvc) const
void initializeSession(const std::vector< uint8_t > &openSecureSessionDataOut, const uint8_t kif, const uint8_t kvc, const bool isSessionEncrypted, const bool isVerificationMode)
std::shared_ptr< uint8_t > computeKvc(const WriteAccessLevel writeAccessLevel, const std::shared_ptr< uint8_t > kvc) const
const std::shared_ptr< CmdSamCardCipherPin > prepareCardCipherPin(const std::vector< uint8_t > ¤tPin, const std::vector< uint8_t > &newPin)
SamTransactionManager & processCommands() override
virtual std::vector< std::shared_ptr< AbstractApduCommand > > & getSamCommands()
SamTransactionManager & processCommands() override
void prepareSelectDiversifierIfNeeded()