Keyple Card Calypso C++ Library - 3.2.2
Component of the Keyple C++ middleware
CommandPutData.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
5 * regarding * copyright ownership.
6 * *
7 * *
8 * This program and the accompanying materials are made available under the
9 * terms of the Eclipse *
10 * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 *
11 * *
12 * SPDX-License-Identifier: EPL-2.0 *
13 **************************************************************************************************/
14
15#include "keyple/card/calypso/CommandPutData.hpp"
16
17#include <algorithm>
18#include <iterator>
19#include <map>
20#include <memory>
21#include <vector>
22
23#include "keyple/card/calypso/CalypsoCardAdapter.hpp"
24#include "keyple/card/calypso/CalypsoCardConstant.hpp"
25#include "keyple/card/calypso/CardAccessForbiddenException.hpp"
26#include "keyple/card/calypso/CardDataAccessException.hpp"
27#include "keyple/card/calypso/CardIllegalParameterException.hpp"
28#include "keyple/card/calypso/CardSecurityContextException.hpp"
29#include "keyple/card/calypso/CardSecurityDataException.hpp"
30#include "keyple/card/calypso/CardSessionBufferOverflowException.hpp"
31#include "keyple/core/util/ApduUtil.hpp"
32#include "keyple/core/util/cpp/Arrays.hpp"
33#include "keyple/core/util/cpp/System.hpp"
34#include "keyple/core/util/cpp/exception/UnsupportedOperationException.hpp"
35
36namespace keyple {
37namespace card {
38namespace calypso {
39
40using keyple::core::util::ApduUtil;
41using keyple::core::util::cpp::Arrays;
42using keyple::core::util::cpp::System;
43using keyple::core::util::cpp::exception::UnsupportedOperationException;
44
45const std::map<int, const std::shared_ptr<Command::StatusProperties>>
46 CommandPutData::STATUS_TABLE = [] {
47 std::map<int, const std::shared_ptr<Command::StatusProperties>> m(
48 Command::STATUS_TABLE);
49
50 m.insert(
51 {{0x6400,
52 std::make_shared<StatusProperties>(
53 "Too many modifications in session",
54 typeid(CardSessionBufferOverflowException))},
55 {0x6700,
56 std::make_shared<StatusProperties>(
57 "Lc value not supported", typeid(CardDataAccessException))},
58 {0x6982,
59 std::make_shared<StatusProperties>(
60 "Security conditions not fulfilled",
61 typeid(CardSecurityContextException))},
62 {0x6985,
63 std::make_shared<StatusProperties>(
64 "Access forbidden", typeid(CardAccessForbiddenException))},
65 {0x6A80,
66 std::make_shared<StatusProperties>(
67 "Lc not compatible with P1P2",
68 typeid(CardIllegalParameterException))},
69 {0x6A87,
70 std::make_shared<StatusProperties>(
71 "Incorrect incoming data",
72 typeid(CardIllegalParameterException))},
73 {0x6A88,
74 std::make_shared<StatusProperties>(
75 "Data object not found", typeid(CardDataAccessException))},
76 {0x6A8A,
77 std::make_shared<StatusProperties>(
78 "Incorrect AID", typeid(CardIllegalParameterException))},
79 {0x6B00,
80 std::make_shared<StatusProperties>(
81 "Incorrect P1, P2", typeid(CardIllegalParameterException))},
82 {0x6D00,
83 std::make_shared<StatusProperties>(
84 "Command Put Data not supported",
85 typeid(CardIllegalParameterException))}});
86 return m;
87 }();
88
89CommandPutData::CommandPutData(
90 const std::shared_ptr<DtoAdapters::TransactionContextDto>&
91 transactionContext,
92 const std::shared_ptr<DtoAdapters::CommandContextDto>& commandContext,
93 PutDataTag tag,
94 bool isFirstPart,
95 const std::vector<std::uint8_t>& data)
96: Command(CardCommandRef::PUT_DATA, 0, transactionContext, commandContext)
97, mTag(tag)
98, mData(data)
99, mIsFirstPart(isFirstPart)
100{
101 std::uint8_t tagMsb;
102 std::uint8_t tagLsb;
103 std::vector<std::uint8_t> dataIn;
104
105 switch (tag) {
106 case PutDataTag::CARD_KEY_PAIR:
107 tagMsb = CalypsoCardConstant::TAG_CARD_KEY_PAIR_MSB;
108 tagLsb = CalypsoCardConstant::TAG_CARD_KEY_PAIR_LSB;
109 dataIn = data;
110 break;
111 case PutDataTag::CARD_CERTIFICATE:
112 tagMsb = CalypsoCardConstant::TAG_CARD_CERTIFICATE_MSB;
113 tagLsb = isFirstPart
114 ? CalypsoCardConstant::TAG_CARD_CERTIFICATE_LSB
115 : CalypsoCardConstant::TAG_CARD_CERTIFICATE_LSB + 1;
116 if (isFirstPart) {
117 dataIn = CalypsoCardConstant::TAG_CARD_CERTIFICATE_HEADER;
118 dataIn.insert(
119 dataIn.end(),
120 std::make_move_iterator(data.begin()),
121 std::make_move_iterator(data.end()));
122 } else {
123 dataIn = data;
124 }
125 break;
126 case PutDataTag::CA_CERTIFICATE:
127 tagMsb = CalypsoCardConstant::TAG_CA_CERTIFICATE_MSB;
128 tagLsb = isFirstPart ? CalypsoCardConstant::TAG_CA_CERTIFICATE_LSB
129 : CalypsoCardConstant::TAG_CA_CERTIFICATE_LSB + 1;
130 if (isFirstPart) {
131 dataIn = CalypsoCardConstant::TAG_CA_CERTIFICATE_HEADER;
132 dataIn.insert(
133 dataIn.end(),
134 std::make_move_iterator(data.begin()),
135 std::make_move_iterator(data.end()));
136 } else {
137 dataIn = data;
138 }
139 break;
140 default:
141 throw UnsupportedOperationException(
142 "Unsupported PutDataTag: " + std::to_string(static_cast<int>(tag)));
143 }
144
145 /* APDU Case 3 - always outside secure session */
146 setApduRequest(
147 std::make_shared<DtoAdapters::ApduRequestAdapter>(ApduUtil::build(
148 getTransactionContext()->getCard()->getCardClass().getValue(),
149 getCommandRef().getInstructionByte(),
150 tagMsb,
151 tagLsb,
152 dataIn)));
153}
154
155void
156CommandPutData::finalizeRequest()
157{
158 /* NOP */
159}
160
161bool
162CommandPutData::isCryptoServiceRequiredToFinalizeRequest() const
163{
164 return false;
165}
166
167bool
168CommandPutData::synchronizeCryptoServiceBeforeCardProcessing()
169{
170 return true;
171}
172
173void
174CommandPutData::parseResponse(std::shared_ptr<ApduResponseApi> apduResponse)
175{
176 Command::setApduResponseAndCheckStatus(apduResponse);
177
178 if (mTag == PutDataTag::CARD_KEY_PAIR) {
179 getTransactionContext()->getCard()->setCardPublicKey(
180 Arrays::copyOf(mData, CalypsoCardConstant::CARD_PUBLIC_KEY_SIZE));
181
182 } else if (mTag == PutDataTag::CARD_CERTIFICATE) {
183 getTransactionContext()->getCard()->addCardCertificateBytes(
184 mData, mIsFirstPart);
185
186 } else if (mTag == PutDataTag::CA_CERTIFICATE) {
187 getTransactionContext()->getCard()->addCaCertificateBytes(
188 mData, mIsFirstPart);
189 }
190}
191
192const std::map<int, const std::shared_ptr<Command::StatusProperties>>&
193CommandPutData::getStatusTable() const
194{
195 return STATUS_TABLE;
196}
197
198} /* namespace calypso */
199} /* namespace card */
200} /* namespace keyple */