Keyple Card Calypso C++ Library - 3.2.2
Component of the Keyple C++ middleware
CommandChangePin.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/CommandChangePin.hpp"
15
16#include <map>
17#include <memory>
18#include <string>
19#include <vector>
20
21#include "keyple/card/calypso/CardAccessForbiddenException.hpp"
22#include "keyple/card/calypso/CardIllegalParameterException.hpp"
23#include "keyple/card/calypso/CardSecurityContextException.hpp"
24#include "keyple/card/calypso/CardSecurityDataException.hpp"
25#include "keyple/card/calypso/CardTerminatedException.hpp"
26#include "keyple/core/util/ApduUtil.hpp"
27#include "keypop/calypso/card/transaction/CryptoException.hpp"
28#include "keypop/calypso/card/transaction/CryptoIOException.hpp"
29#include "keypop/calypso/card/transaction/InvalidPinException.hpp"
30#include "keypop/calypso/crypto/symmetric/SymmetricCryptoException.hpp"
31#include "keypop/calypso/crypto/symmetric/SymmetricCryptoIOException.hpp"
32
33namespace keyple {
34namespace card {
35namespace calypso {
36
37using keyple::core::util::ApduUtil;
38using keypop::calypso::card::transaction::CryptoException;
39using keypop::calypso::card::transaction::CryptoIOException;
40using keypop::calypso::card::transaction::InvalidPinException;
41using keypop::calypso::crypto::symmetric::SymmetricCryptoException;
42using keypop::calypso::crypto::symmetric::SymmetricCryptoIOException;
43
44const std::map<int, const std::shared_ptr<Command::StatusProperties>>
45 CommandChangePin::STATUS_TABLE = [] {
46 std::map<int, const std::shared_ptr<Command::StatusProperties>> m(
47 Command::STATUS_TABLE);
48
49 m.insert(
50 {{0x6700,
51 std::make_shared<StatusProperties>(
52 "Lc value not supported (not 04h, 10h, 18h, 20h)",
53 typeid(CardIllegalParameterException))},
54 {0x6900,
55 std::make_shared<StatusProperties>(
56 "Transaction Counter is 0", typeid(CardTerminatedException))},
57 {0x6982,
58 std::make_shared<StatusProperties>(
59 std::string("Security conditions not satisfied (Get ")
60 + "Challenge not done: challenge unavailable)",
61 typeid(CardSecurityContextException))},
62 {0x6985,
63 std::make_shared<StatusProperties>(
64 "Access forbidden (a session is open or DF is invalidated)",
65 typeid(CardAccessForbiddenException))},
66 {0x6988,
67 std::make_shared<StatusProperties>(
68 "Incorrect Cryptogram", typeid(CardSecurityDataException))},
69 {0x6A80,
70 std::make_shared<StatusProperties>(
71 "Decrypted message incorrect (key algorithm not supported, "
72 "incorrect padding, etc.",
73 typeid(CardSecurityDataException))},
74 {0x6A87,
75 std::make_shared<StatusProperties>(
76 "Lc not compatible with P2",
77 typeid(CardIllegalParameterException))},
78 {0x6B00,
79 std::make_shared<StatusProperties>(
80 "Incorrect P1, P2", typeid(CardIllegalParameterException))}});
81 return m;
82 }();
83
84CommandChangePin::CommandChangePin(
85 const std::shared_ptr<DtoAdapters::TransactionContextDto>&
86 transactionContext,
87 const std::shared_ptr<DtoAdapters::CommandContextDto>& commandContext,
88 const std::vector<std::uint8_t>& pin)
89: Command(CardCommandRef::CHANGE_PIN, 0, transactionContext, commandContext)
90, mPin(pin)
91, mIsPinEncryptedMode(false)
92, mCipheringKif(0)
93, mCipheringKvc(0)
94{
95}
96
97CommandChangePin::CommandChangePin(
98 const std::shared_ptr<DtoAdapters::TransactionContextDto>&
99 transactionContext,
100 const std::shared_ptr<DtoAdapters::CommandContextDto>& commandContext,
101 const std::vector<std::uint8_t>& pin,
102 std::uint8_t cipheringKif,
103 std::uint8_t cipheringKvc)
104: Command(CardCommandRef::CHANGE_PIN, 0, transactionContext, commandContext)
105, mPin(pin)
106, mIsPinEncryptedMode(true)
107, mCipheringKif(cipheringKif)
108, mCipheringKvc(cipheringKvc)
109{
110}
111
112void
113CommandChangePin::finalizeRequest()
114{
115 if (mIsPinEncryptedMode) {
116 try {
117 mPin = getTransactionContext()
118 ->getSymmetricCryptoCardTransactionManagerSpi()
119 ->cipherPinForModification(
120 getTransactionContext()->getCard()->getChallenge(),
121 std::vector<std::uint8_t>(4),
122 mPin,
123 std::make_shared<std::uint8_t>(mCipheringKif),
124 std::make_shared<std::uint8_t>(mCipheringKvc));
125
126 } catch (const SymmetricCryptoException& e) {
127 throw CryptoException(e.what(), e);
128
129 } catch (const SymmetricCryptoIOException& e) {
130 throw CryptoIOException(e.what(), e);
131 }
132 }
133
134 /* APDU Case 3 */
135 setApduRequest(
136 std::make_shared<DtoAdapters::ApduRequestAdapter>(ApduUtil::build(
137 getTransactionContext()->getCard()->getCardClass().getValue(),
138 getCommandRef().getInstructionByte(),
139 0x00, /* CL-PIN-MP1P2.1 */
140 0xFF,
141 mPin)));
142}
143
144bool
145CommandChangePin::isCryptoServiceRequiredToFinalizeRequest() const
146{
147 return mIsPinEncryptedMode;
148}
149
150bool
151CommandChangePin::synchronizeCryptoServiceBeforeCardProcessing()
152{
153 return true;
154}
155
156void
157CommandChangePin::parseResponse(std::shared_ptr<ApduResponseApi> apduResponse)
158{
159 Command::setApduResponseAndCheckStatus(apduResponse);
160 /*
161 * The PIN has been successfully updated, and the presentation counter is
162 * reset to zero.
163 */
164 getTransactionContext()->getCard()->setPinAttemptRemaining(3);
165}
166
167const std::map<int, const std::shared_ptr<Command::StatusProperties>>&
168CommandChangePin::getStatusTable() const
169{
170 return STATUS_TABLE;
171}
172
173} /* namespace calypso */
174} /* namespace card */
175} /* namespace keyple */