Keyple Card Calypso C++ Library 2.2.5.6
Reference Terminal Reader API for C++
CmdCardSvReload.cpp
Go to the documentation of this file.
1/**************************************************************************************************
2 * Copyright (c) 2023 Calypso Networks Association https://calypsonet.org/ *
3 * *
4 * See the NOTICE file(s) distributed with this work for additional information regarding *
5 * copyright ownership. *
6 * *
7 * This program and the accompanying materials are made available under the terms of the Eclipse *
8 * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 *
9 * *
10 * SPDX-License-Identifier: EPL-2.0 *
11 **************************************************************************************************/
12
13#include "CmdCardSvReload.h"
14
15/* Keyple Card Calypso */
16#include "CalypsoCardAdapter.h"
17#include "CalypsoCardClass.h"
23#include "SamUtilAdapter.h"
24
25/* Keyple Core Util */
26#include "ApduUtil.h"
27#include "ByteArrayUtil.h"
28#include "IllegalArgumentException.h"
29#include "IllegalStateException.h"
30#include "System.h"
31
32namespace keyple {
33namespace card {
34namespace calypso {
35
36using namespace keyple::core::util;
37using namespace keyple::core::util::cpp;
38using namespace keyple::core::util::cpp::exception;
39
40const int CmdCardSvReload::SW_POSTPONED_DATA = 0x6200;
41const CalypsoCardCommand CmdCardSvReload::mCommand = CalypsoCardCommand::SV_RELOAD;
42
43const std::map<const int, const std::shared_ptr<StatusProperties>>
44 CmdCardSvReload::STATUS_TABLE = initStatusTable();
45
46CmdCardSvReload::CmdCardSvReload(const std::shared_ptr<CalypsoCardAdapter> calypsoCard,
47 const int amount,
48 const std::vector<uint8_t>& date,
49 const std::vector<uint8_t>& time,
50 const std::vector<uint8_t>& free,
51 const bool isSessionOpen,
52 const bool isExtendedModeAllowed)
53: AbstractCardCommand(mCommand, -1, calypsoCard),
54 /* Keeps a copy of these fields until the builder is finalized */
55 mIsSessionOpen(isSessionOpen),
56 mIsExtendedModeAllowed(isExtendedModeAllowed)
57{
58 if (amount < -8388608 || amount > 8388607) {
59
60 throw IllegalArgumentException("Amount is outside allowed boundaries (-8388608 <= amount " \
61 "<= 8388607)");
62 }
63
64 if (date.empty() || time.empty() || free.empty()) {
65
66 throw IllegalArgumentException("date, time and free cannot be null");
67 }
68
69 if (date.size() != 2 || time.size() != 2 || free.size() != 2) {
70
71 throw IllegalArgumentException("date, time and free must be 2-byte arrays");
72 }
73
74 /*
75 * Handle the dataIn size with signatureHi length according to card revision (3.2 rev have a
76 * 10-byte signature)
77 */
78 mDataIn = std::vector<uint8_t>(18 + (isExtendedModeAllowed ? 10 : 5));
79
80 /* dataIn[0] will be filled in at the finalization phase */
81 mDataIn[1] = date[0];
82 mDataIn[2] = date[1];
83 mDataIn[3] = free[0];
84 mDataIn[4] = calypsoCard->getSvKvc();
85 mDataIn[5] = free[1];
86 ByteArrayUtil::copyBytes(amount, mDataIn, 6, 3);
87 mDataIn[9] = time[0];
88 mDataIn[10] = time[1];
89 /* mDataIn[11]..mDataIn[11+7+sigLen] will be filled in at the finalization phase */
90}
91
92void CmdCardSvReload::finalizeCommand(const std::vector<uint8_t>& reloadComplementaryData)
93{
94 if ((mIsExtendedModeAllowed && reloadComplementaryData.size() != 20) ||
95 (!mIsExtendedModeAllowed && reloadComplementaryData.size() != 15)) {
96 throw IllegalArgumentException("Bad SV prepare load data length.");
97 }
98
99 uint8_t le;
100
101 if (mIsSessionOpen) {
102 le = 0;
103 } else {
104 if(mIsExtendedModeAllowed) {
105 le = 6;
106 } else {
107 le = 3;
108 }
109 }
110
112
113 const uint8_t p1 = reloadComplementaryData[4];
114 const uint8_t p2 = reloadComplementaryData[5];
115
116 mDataIn[0] = reloadComplementaryData[6];
117 System::arraycopy(reloadComplementaryData, 0, mDataIn, 11, 4);
118 System::arraycopy(reloadComplementaryData, 7, mDataIn, 15, 3);
119 System::arraycopy(reloadComplementaryData, 10, mDataIn, 18, reloadComplementaryData.size()-10);
120
121 const uint8_t cardClass = getCalypsoCard()->getCardClass() == CalypsoCardClass::LEGACY ?
124
125 std::shared_ptr<ApduRequestAdapter> apduRequest;
126 if (le == 0) {
127 // APDU Case 3
128 apduRequest = std::make_shared<ApduRequestAdapter>(
129 ApduUtil::build(cardClass,
130 mCommand.getInstructionByte(),
131 p1,
132 p2,
133 mDataIn));
134 } else {
135 // APDU Case 4
136 apduRequest = std::make_shared<ApduRequestAdapter>(
137 ApduUtil::build(cardClass,
138 mCommand.getInstructionByte(),
139 p1,
140 p2,
141 mDataIn,
142 le));
143 }
144 apduRequest->addSuccessfulStatusWord(SW_POSTPONED_DATA);
145 setApduRequest(apduRequest);
146}
147
148const std::vector<uint8_t> CmdCardSvReload::getSvReloadData() const
149{
150 std::vector<uint8_t> svReloadData(15);
151
152 svReloadData[0] = mCommand.getInstructionByte();
153
154 /*
155 * svReloadData[1,2] / P1P2 not set because ignored
156 * Lc is 5 bytes longer in revision 3.2
157 */
158 svReloadData[3] = mIsExtendedModeAllowed ? 0x1C : 0x17;
159
160 /* Appends the fixed part of dataIn */
161 System::arraycopy(mDataIn, 0, svReloadData, 4, 11);
162
163 return svReloadData;
164}
165
167{
168 return true;
169}
170
171void CmdCardSvReload::parseApduResponse(const std::shared_ptr<ApduResponseApi> apduResponse)
172{
174
175 const std::vector<uint8_t> dataOut = apduResponse->getDataOut();
176
177 if (dataOut.size() != 0 && dataOut.size() != 3 && dataOut.size() != 6) {
178
179 throw IllegalStateException("Bad length in response to SV Reload command.");
180 }
181
182 getCalypsoCard()->setSvOperationSignature(apduResponse->getDataOut());
183}
184
185const std::vector<uint8_t> CmdCardSvReload::getSignatureLo() const
186{
187 return getApduResponse()->getDataOut();
188}
189
190const std::map<const int, const std::shared_ptr<StatusProperties>>
191 CmdCardSvReload::initStatusTable()
192{
193 std::map<const int, const std::shared_ptr<StatusProperties>> m =
195
196 m.insert({SW_POSTPONED_DATA,
197 std::make_shared<StatusProperties>("Successful execution, response data postponed " \
198 "until session closing.",
199 typeid(nullptr))});
200 m.insert({0x6400,
201 std::make_shared<StatusProperties>("Too many modifications in session.",
202 typeid(CardSessionBufferOverflowException))});
203 m.insert({0x6700,
204 std::make_shared<StatusProperties>("Lc value not supported.",
205 typeid(CardIllegalParameterException))});
206 m.insert({0x6900,
207 std::make_shared<StatusProperties>("Transaction counter is 0 or SV TNum is FFFEh or" \
208 " FFFFh.",
209 typeid(CalypsoSamCounterOverflowException))});
210 m.insert({0x6985,
211 std::make_shared<StatusProperties>("Preconditions not satisfied.",
212 typeid(CalypsoSamAccessForbiddenException))});
213 m.insert({0x6988,
214 std::make_shared<StatusProperties>("Incorrect signatureHi.",
215 typeid(CardSecurityDataException))});
216
217 return m;
218}
219
220const std::map<const int, const std::shared_ptr<StatusProperties>>&
222{
223 return STATUS_TABLE;
224}
225
226}
227}
228}
static const std::map< const int, const std::shared_ptr< StatusProperties > > STATUS_TABLE
virtual const std::shared_ptr< ApduResponseApi > getApduResponse() const final
virtual void setApduRequest(const std::shared_ptr< ApduRequestAdapter > apduRequest) final
virtual void setExpectedResponseLength(const int expectedResponseLength) 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 CalypsoCardClass LEGACY_STORED_VALUE
static const CalypsoCardCommand SV_RELOAD
void parseApduResponse(const std::shared_ptr< ApduResponseApi > apduResponse) override
const std::vector< uint8_t > getSvReloadData() const
const std::vector< uint8_t > getSignatureLo() const
CmdCardSvReload(const std::shared_ptr< CalypsoCardAdapter > calypsoCard, const int amount, const std::vector< uint8_t > &date, const std::vector< uint8_t > &time, const std::vector< uint8_t > &free, const bool isSessionOpen, const bool isExtendedModeAllowed)
const std::map< const int, const std::shared_ptr< StatusProperties > > & getStatusTable() const override
void finalizeCommand(const std::vector< uint8_t > &reloadComplementaryData)