Keyple Card Calypso C++ Library - 3.2.2
Component of the Keyple C++ middleware
CommandChangeKey.cpp
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ *
3 * *
4 * See the NOTICE file(s) distributed with this work for additional *
5 * information regarding copyright ownership. *
6 * *
7 * This program and the accompanying materials are made available under the *
8 * terms of the Eclipse Public License 2.0 which is available at *
9 * http://www.eclipse.org/legal/epl-2.0 *
10 * *
11 * SPDX-License-Identifier: EPL-2.0 *
12 ******************************************************************************/
13
14#include "keyple/card/calypso/CommandChangeKey.hpp"
15
16#include <map>
17#include <memory>
18#include <string>
19#include <vector>
20
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/CardSecurityContextException.hpp"
25#include "keyple/card/calypso/CardSecurityDataException.hpp"
26#include "keyple/card/calypso/CardTerminatedException.hpp"
27#include "keyple/core/util/ApduUtil.hpp"
28#include "keyple/core/util/HexUtil.hpp"
29#include "keyple/core/util/cpp/exception/IllegalStateException.hpp"
30#include "keypop/calypso/card/transaction/CryptoException.hpp"
31#include "keypop/calypso/card/transaction/CryptoIOException.hpp"
32#include "keypop/calypso/crypto/symmetric/SymmetricCryptoException.hpp"
33#include "keypop/calypso/crypto/symmetric/SymmetricCryptoIOException.hpp"
34
35namespace keyple {
36namespace card {
37namespace calypso {
38
39using keyple::core::util::ApduUtil;
40using keyple::core::util::HexUtil;
41using keyple::core::util::cpp::exception::IllegalStateException;
42using keypop::calypso::card::transaction::CryptoException;
43using keypop::calypso::card::transaction::CryptoIOException;
44using keypop::calypso::crypto::symmetric::SymmetricCryptoException;
45using keypop::calypso::crypto::symmetric::SymmetricCryptoIOException;
46
47const std::map<int, const std::shared_ptr<Command::StatusProperties>>
48 CommandChangeKey::STATUS_TABLE = [] {
49 std::map<int, const std::shared_ptr<Command::StatusProperties>> m(
50 Command::STATUS_TABLE);
51
52 m.insert(
53 {{0x6700,
54 std::make_shared<StatusProperties>(
55 "Lc value not supported (not 04h, 10h, 18h, 20h)",
56 typeid(CardIllegalParameterException))},
57 {0x6900,
58 std::make_shared<StatusProperties>(
59 "Transaction Counter is 0", typeid(CardTerminatedException))},
60 {0x6982,
61 std::make_shared<StatusProperties>(
62 std::string("Security conditions not satisfied (Get ")
63 + "Challenge not done: challenge unavailable)",
64 typeid(CardSecurityContextException))},
65 {0x6985,
66 std::make_shared<StatusProperties>(
67 "Access forbidden (a session is open or DF is invalidated)",
68 typeid(CardAccessForbiddenException))},
69 {0x6988,
70 std::make_shared<StatusProperties>(
71 "Incorrect Cryptogram", typeid(CardSecurityDataException))},
72 {0x6A80,
73 std::make_shared<StatusProperties>(
74 "Decrypted message incorrect (key algorithm not supported, "
75 "incorrect padding, etc.",
76 typeid(CardSecurityDataException))},
77 {0x6A87,
78 std::make_shared<StatusProperties>(
79 "Lc not compatible with P2",
80 typeid(CardIllegalParameterException))},
81 {0x6B00,
82 std::make_shared<StatusProperties>(
83 "Incorrect P1, P2", typeid(CardIllegalParameterException))}});
84 return m;
85 }();
86
87CommandChangeKey::CommandChangeKey(
88 const std::shared_ptr<DtoAdapters::TransactionContextDto>&
89 transactionContext,
90 const std::shared_ptr<DtoAdapters::CommandContextDto>& commandContext,
91 std::uint8_t keyIndex,
92 std::uint8_t newKif,
93 std::uint8_t newKvc,
94 std::uint8_t issuerKif,
95 std::uint8_t issuerKvc)
96: Command(CardCommandRef::CHANGE_KEY, 0, transactionContext, commandContext)
97, mKeyIndex(keyIndex)
98, mNewKif(newKif)
99, mNewKvc(newKvc)
100, mIssuerKif(issuerKif)
101, mIssuerKvc(issuerKvc)
102{
103}
104
105void
106CommandChangeKey::finalizeRequest()
107{
108 std::vector<std::uint8_t> cipheredKey;
109
110 try {
111 cipheredKey
112 = getTransactionContext()
113 ->getSymmetricCryptoCardTransactionManagerSpi()
114 ->generateCipheredCardKey(
115 getTransactionContext()->getCard()->getChallenge(),
116 mIssuerKif,
117 mIssuerKvc,
118 mNewKif,
119 mNewKvc);
120
121 } catch (const SymmetricCryptoException& e) {
122 throw CryptoException(e.what(), e);
123
124 } catch (const SymmetricCryptoIOException& e) {
125 throw CryptoIOException(e.what(), e);
126 }
127
128 /* APDU Case 3 */
129 setApduRequest(
130 std::make_shared<DtoAdapters::ApduRequestAdapter>(ApduUtil::build(
131 getTransactionContext()->getCard()->getCardClass().getValue(),
132 getCommandRef().getInstructionByte(),
133 0x00,
134 mKeyIndex,
135 cipheredKey)));
136}
137
138bool
139CommandChangeKey::isCryptoServiceRequiredToFinalizeRequest() const
140{
141 return true;
142}
143
144bool
145CommandChangeKey::synchronizeCryptoServiceBeforeCardProcessing()
146{
147 return true;
148}
149
150void
151CommandChangeKey::parseResponse(std::shared_ptr<ApduResponseApi> apduResponse)
152{
153 Command::setApduResponseAndCheckStatus(apduResponse);
154}
155
156const std::map<int, const std::shared_ptr<Command::StatusProperties>>&
157CommandChangeKey::getStatusTable() const
158{
159 return STATUS_TABLE;
160}
161
162} /* namespace calypso */
163} /* namespace card */
164} /* namespace keyple */