14#include "keyple/card/calypso/CommandCloseSecureSession.hpp"
21#include "keyple/card/calypso/CalypsoCardAdapter.hpp"
22#include "keyple/card/calypso/CardAccessForbiddenException.hpp"
23#include "keyple/card/calypso/CardIllegalParameterException.hpp"
24#include "keyple/card/calypso/CardSecurityDataException.hpp"
25#include "keyple/core/util/ApduUtil.hpp"
26#include "keyple/core/util/cpp/Arrays.hpp"
27#include "keypop/calypso/card/transaction/CardSignatureNotVerifiableException.hpp"
28#include "keypop/calypso/card/transaction/CryptoException.hpp"
29#include "keypop/calypso/card/transaction/CryptoIOException.hpp"
30#include "keypop/calypso/card/transaction/InvalidCardSignatureException.hpp"
31#include "keypop/calypso/crypto/asymmetric/AsymmetricCryptoException.hpp"
32#include "keypop/calypso/crypto/symmetric/SymmetricCryptoException.hpp"
33#include "keypop/calypso/crypto/symmetric/SymmetricCryptoIOException.hpp"
39using keyple::core::util::ApduUtil;
40using keyple::core::util::cpp::Arrays;
41using keypop::calypso::card::transaction::CardSignatureNotVerifiableException;
42using keypop::calypso::card::transaction::CryptoException;
43using keypop::calypso::card::transaction::CryptoIOException;
44using keypop::calypso::card::transaction::InvalidCardSignatureException;
45using keypop::calypso::crypto::asymmetric::AsymmetricCryptoException;
46using keypop::calypso::crypto::symmetric::SymmetricCryptoException;
47using keypop::calypso::crypto::symmetric::SymmetricCryptoIOException;
49const std::string CommandCloseSecureSession::MSG_CARD_SESSION_MAC_NOT_VERIFIABLE
50 =
"Unable to verify the card session MAC associated to the successfully "
51 "closed secure session";
52const std::string CommandCloseSecureSession::MSG_CARD_SV_MAC_NOT_VERIFIABLE
53 =
"Unable to verify the card SV MAC associated to the SV operation";
54const std::string CommandCloseSecureSession::MSG_INVALID_CARD_SESSION_MAC
55 =
"Invalid card session MAC";
56const std::string CommandCloseSecureSession::MSG_INVALID_CARD_SESSION_SIGNATURE
57 =
"Invalid card session signature";
59const CardCommandRef CommandCloseSecureSession::mCommandRef
60 = CardCommandRef::CLOSE_SECURE_SESSION;
62const std::map<int, const std::shared_ptr<Command::StatusProperties>>
63 CommandCloseSecureSession::STATUS_TABLE = [] {
64 std::map<int, const std::shared_ptr<Command::StatusProperties>> m(
65 Command::STATUS_TABLE);
69 std::make_shared<StatusProperties>(
70 "Lc signatureLo not supported (e.g. Lc=4 with a Revision 3.2 "
71 "mode for Open Secure Session)",
72 typeid(CardIllegalParameterException))},
74 std::make_shared<StatusProperties>(
75 "P1 or P2 signatureLo not supported",
76 typeid(CardIllegalParameterException))},
78 std::make_shared<StatusProperties>(
79 "No session was opened",
80 typeid(CardAccessForbiddenException))},
82 std::make_shared<StatusProperties>(
83 "Incorrect signatureLo",
84 typeid(CardSecurityDataException))}});
88CommandCloseSecureSession::CommandCloseSecureSession(
89 const std::shared_ptr<DtoAdapters::TransactionContextDto>&
91 const std::shared_ptr<DtoAdapters::CommandContextDto>& commandContext,
92 bool isAutoRatificationAsked,
93 int svPostponedDataIndex)
95: Command(mCommandRef, nullptr, transactionContext, commandContext)
96, mIsAutoRatificationAsked(isAutoRatificationAsked)
97, mIsAbortSecureSession(false)
98, mSvPostponedDataIndex(svPostponedDataIndex)
102CommandCloseSecureSession::CommandCloseSecureSession(
103 const std::shared_ptr<DtoAdapters::TransactionContextDto>&
105 const std::shared_ptr<DtoAdapters::CommandContextDto>& commandContext,
110 isAbort ? std::unique_ptr<int>(new int(0)) : nullptr,
113, mIsAutoRatificationAsked(true)
114, mSvPostponedDataIndex(-1)
116 if (transactionContext->isPkiMode()) {
124 std::make_shared<DtoAdapters::ApduRequestAdapter>(ApduUtil::build(
125 getTransactionContext()->getCard()->getCardClass().getValue(),
126 mCommandRef.getInstructionByte(),
129 mIsAbortSecureSession = isAbort;
133 mIsAbortSecureSession =
true;
138CommandCloseSecureSession::finalizeRequest()
140 if (mIsAbortSecureSession) {
147 std::make_shared<DtoAdapters::ApduRequestAdapter>(ApduUtil::build(
148 getTransactionContext()->getCard()->getCardClass().getValue(),
149 mCommandRef.getInstructionByte(),
155 std::vector<std::uint8_t> terminalSessionMac;
158 = getTransactionContext()
159 ->getSymmetricCryptoCardTransactionManagerSpi()
160 ->finalizeTerminalSessionMac();
162 }
catch (
const SymmetricCryptoException& e) {
163 throw CryptoException(e.what(), e);
165 }
catch (
const SymmetricCryptoIOException& e) {
166 throw CryptoIOException(e.what(), e);
171 std::make_shared<DtoAdapters::ApduRequestAdapter>(ApduUtil::build(
172 getTransactionContext()->getCard()->getCardClass().getValue(),
173 mCommandRef.getInstructionByte(),
174 mIsAutoRatificationAsked ? 0x80 : 0x00,
182CommandCloseSecureSession::isCryptoServiceRequiredToFinalizeRequest()
const
184 return !mIsAbortSecureSession;
188CommandCloseSecureSession::synchronizeCryptoServiceBeforeCardProcessing()
190 return mIsAbortSecureSession;
194CommandCloseSecureSession::parseResponse(
195 std::shared_ptr<ApduResponseApi> apduResponse)
197 if (mIsAbortSecureSession) {
198 processAbort(apduResponse);
202 Command::setApduResponseAndCheckStatus(apduResponse);
203 getTransactionContext()->setSecureSessionOpen(
false);
205 const std::vector<std::uint8_t> responseData
206 = getApduResponse()->getDataOut();
208 if (getTransactionContext()->isPkiMode()) {
209 parseResponseInAsymmetricMode(responseData);
211 parseResponseInSymmetricMode(responseData);
216CommandCloseSecureSession::processAbort(
217 std::shared_ptr<ApduResponseApi> apduResponse)
219 getTransactionContext()->setSecureSessionOpen(
false);
222 Command::setApduResponseAndCheckStatus(apduResponse);
223 mLogger->info(
"Secure session aborted\n");
224 getTransactionContext()->getCard()->restoreFiles();
226 }
catch (
const CardCommandException& e) {
228 "Failed to abort secure session [reason=%]\n", e.getMessage());
233CommandCloseSecureSession::parseResponseInSymmetricMode(
234 const std::vector<std::uint8_t>& responseData)
237 const int cardSessionMacLength
238 = getTransactionContext()->getCard()->isExtendedModeSupported() ? 8 : 4;
241 while (i <
static_cast<int>(responseData.size() - cardSessionMacLength)) {
243 = Arrays::copyOfRange(responseData, i + 1, i + responseData[i]);
244 mPostponedData.push_back(data);
245 i += responseData[i];
249 const auto cardSessionMac
250 = Arrays::copyOfRange(responseData, i, responseData.size());
253 if (!getTransactionContext()
254 ->getSymmetricCryptoCardTransactionManagerSpi()
255 ->isCardSessionMacValid(cardSessionMac)) {
256 throw InvalidCardSignatureException(MSG_INVALID_CARD_SESSION_MAC);
259 }
catch (
const SymmetricCryptoIOException& e) {
260 throw CardSignatureNotVerifiableException(
261 MSG_CARD_SESSION_MAC_NOT_VERIFIABLE, e);
263 }
catch (
const SymmetricCryptoException& e) {
264 throw CryptoException(e.what(), e);
267 if (mSvPostponedDataIndex != -1) {
270 if (!getTransactionContext()
271 ->getSymmetricCryptoCardTransactionManagerSpi()
273 mPostponedData[mSvPostponedDataIndex])) {
274 throw InvalidCardSignatureException(
275 MSG_INVALID_CARD_SESSION_MAC);
278 }
catch (
const SymmetricCryptoIOException& e) {
279 throw CardSignatureNotVerifiableException(
280 MSG_CARD_SV_MAC_NOT_VERIFIABLE, e);
282 }
catch (
const SymmetricCryptoException& e) {
283 throw CryptoException(e.what(), e);
288const std::map<int, const std::shared_ptr<Command::StatusProperties>>&
289CommandCloseSecureSession::getStatusTable()
const
295CommandCloseSecureSession::parseResponseInAsymmetricMode(
296 const std::vector<std::uint8_t>& responseData)
299 if (!getTransactionContext()
300 ->getAsymmetricCryptoCardTransactionManagerSpi()
301 ->isCardPkiSessionValid(responseData)) {
302 throw InvalidCardSignatureException(
303 MSG_INVALID_CARD_SESSION_SIGNATURE);
306 }
catch (
const AsymmetricCryptoException& e) {
307 throw CryptoException(e.what(), e);
312CommandCloseSecureSession::incrementSvPostponedDataIndex()
314 mSvPostponedDataIndex++;