14#include "keyple/card/calypso/CommandManageSession.hpp"
22#include "keyple/card/calypso/CalypsoCardAdapter.hpp"
23#include "keyple/card/calypso/CardIllegalParameterException.hpp"
24#include "keyple/card/calypso/CardSecurityContextException.hpp"
25#include "keyple/card/calypso/CardSecurityDataException.hpp"
26#include "keyple/core/util/ApduUtil.hpp"
27#include "keyple/core/util/HexUtil.hpp"
28#include "keyple/core/util/cpp/exception/IllegalStateException.hpp"
29#include "keyple/core/util/cpp/exception/UnsupportedOperationException.hpp"
30#include "keypop/calypso/card/transaction/CryptoException.hpp"
31#include "keypop/calypso/card/transaction/CryptoIOException.hpp"
32#include "keypop/calypso/card/transaction/InvalidCardSignatureException.hpp"
33#include "keypop/calypso/crypto/symmetric/SymmetricCryptoException.hpp"
34#include "keypop/calypso/crypto/symmetric/SymmetricCryptoIOException.hpp"
40using keyple::core::util::ApduUtil;
41using keyple::core::util::HexUtil;
42using keyple::core::util::cpp::exception::IllegalStateException;
43using keyple::core::util::cpp::exception::UnsupportedOperationException;
44using keypop::calypso::card::transaction::CryptoException;
45using keypop::calypso::card::transaction::CryptoIOException;
46using keypop::calypso::card::transaction::InvalidCardSignatureException;
47using keypop::calypso::crypto::symmetric::SymmetricCryptoException;
48using keypop::calypso::crypto::symmetric::SymmetricCryptoIOException;
50const std::map<int, const std::shared_ptr<Command::StatusProperties>>
51 CommandManageSession::STATUS_TABLE = [] {
52 std::map<int, const std::shared_ptr<Command::StatusProperties>> m(
53 Command::STATUS_TABLE);
57 std::make_shared<StatusProperties>(
58 "Lc value not supported",
59 typeid(CardIllegalParameterException))},
61 std::make_shared<StatusProperties>(
62 std::string(
"Preconditions not satisfied:\n")
63 +
"- No secure session running in Extended mode.\n"
64 +
"- Manage Secure Session not authorized during the "
66 +
"session (as indicated by the Flags byte of Open "
69 typeid(CardSecurityDataException))},
71 std::make_shared<StatusProperties>(
72 "Incorrect terminal Session MAC (the secure session is "
74 typeid(CardSecurityDataException))},
76 std::make_shared<StatusProperties>(
77 "Extended mode not supported, or AES keys not supported",
78 typeid(CardSecurityContextException))}});
82CommandManageSession::CommandManageSession(
83 const std::shared_ptr<DtoAdapters::TransactionContextDto>&
85 const std::shared_ptr<DtoAdapters::CommandContextDto>& commandContext)
88 CardCommandRef::MANAGE_SECURE_SESSION,
96CommandManageSession::setEncryptionRequested(
bool isEncryptionRequested)
98 mIsEncryptionRequested = isEncryptionRequested;
104CommandManageSession::setMutualAuthenticationRequested(
105 bool isMutualAuthenticationRequested)
107 mIsMutualAuthenticationRequested = isMutualAuthenticationRequested;
113CommandManageSession::finalizeRequest()
116 std::vector<std::uint8_t> terminalSessionMac;
118 if (mIsMutualAuthenticationRequested) {
123 p2 = mIsEncryptionRequested ? 0x03 : 0x01;
126 = getTransactionContext()
127 ->getSymmetricCryptoCardTransactionManagerSpi()
128 ->generateTerminalSessionMac();
130 }
catch (
const SymmetricCryptoException& e) {
131 throw CryptoException(e.what(), e);
133 }
catch (
const SymmetricCryptoIOException& e) {
134 throw CryptoIOException(e.what(), e);
137 setExpectedResponseLength((std::unique_ptr<int>(
new int(8))));
141 p2 = mIsEncryptionRequested ? 0x02 : 0x00;
142 terminalSessionMac.clear();
143 setExpectedResponseLength(0);
148 std::unique_ptr<DtoAdapters::ApduRequestAdapter>(
149 new DtoAdapters::ApduRequestAdapter(
151 getTransactionContext()
155 getCommandRef().getInstructionByte(),
163const std::map<int, const std::shared_ptr<Command::StatusProperties>>&
164CommandManageSession::getStatusTable()
const
170CommandManageSession::isCryptoServiceRequiredToFinalizeRequest()
const
172 return mIsMutualAuthenticationRequested;
176CommandManageSession::synchronizeCryptoServiceBeforeCardProcessing()
178 if (mIsMutualAuthenticationRequested) {
182 if (!isCryptoServiceSynchronized()) {
183 updateCryptoServiceEncryptionStateIfNeeded();
184 confirmCryptoServiceSuccessfullySynchronized();
191CommandManageSession::parseResponse(
192 std::shared_ptr<ApduResponseApi> apduResponse)
195 Command::setApduResponseAndCheckStatus(apduResponse);
197 }
catch (
const CardSecurityDataException&) {
198 if (apduResponse->getStatusWord() == 0x6985
199 && !getTransactionContext()->getCard()->isExtendedModeSupported()) {
200 throw UnsupportedOperationException(
201 std::string(
"'Manage Secure Session' command is not ")
202 +
"available for this context (Card and/or SAM does not "
203 +
"support extended mode)");
209 const std::vector<std::uint8_t> cardSessionMac
210 = getApduResponse()->getDataOut();
212 if (mIsMutualAuthenticationRequested) {
214 if (!getTransactionContext()
215 ->getSymmetricCryptoCardTransactionManagerSpi()
216 ->isCardSessionMacValid(cardSessionMac)) {
217 throw InvalidCardSignatureException(
218 "Invalid card (authentication failed)");
220 }
catch (
const SymmetricCryptoException& e) {
221 throw new CryptoException(e.what(), e);
223 }
catch (
const SymmetricCryptoIOException& e) {
224 throw new CryptoIOException(e.what(), e);
228 if (!isCryptoServiceSynchronized()) {
229 updateCryptoServiceEncryptionStateIfNeeded();
234CommandManageSession::updateCryptoServiceEncryptionStateIfNeeded()
237 if (!getCommandContext()->isEncryptionActive()
238 && mIsEncryptionRequested) {
239 getTransactionContext()
240 ->getSymmetricCryptoCardTransactionManagerSpi()
241 ->activateEncryption();
244 getCommandContext()->isEncryptionActive()
245 && !mIsEncryptionRequested) {
246 getTransactionContext()
247 ->getSymmetricCryptoCardTransactionManagerSpi()
248 ->deactivateEncryption();
251 }
catch (
const SymmetricCryptoException& e) {
252 throw CryptoException(e.what(), e);
254 }
catch (
const SymmetricCryptoIOException& e) {
255 throw CryptoIOException(e.what(), e);