Keyple Card Calypso C++ Library - 3.2.2
Component of the Keyple C++ middleware
AsymmetricCryptoSecuritySettingAdapter.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/AsymmetricCryptoSecuritySettingAdapter.hpp"
15
16#include <memory>
17#include <string>
18#include <typeinfo>
19#include <vector>
20
21#include "keyple/core/util/HexUtil.hpp"
22#include "keyple/core/util/KeypleAssert.hpp"
23#include "keyple/core/util/cpp/exception/IllegalArgumentException.hpp"
24#include "keyple/core/util/cpp/exception/IllegalStateException.hpp"
25#include "keypop/calypso/card/transaction/CryptoException.hpp"
26#include "keypop/calypso/card/transaction/InvalidCertificateException.hpp"
27#include "keypop/calypso/crypto/asymmetric/AsymmetricCryptoException.hpp"
28#include "keypop/calypso/crypto/asymmetric/certificate/CertificateValidationException.hpp"
29#include "keypop/calypso/crypto/asymmetric/certificate/spi/CaCertificateSpi.hpp"
30#include "keypop/calypso/crypto/asymmetric/certificate/spi/PcaCertificateSpi.hpp"
31
32namespace keyple {
33namespace card {
34namespace calypso {
35
36using keyple::core::util::Assert;
37using keyple::core::util::HexUtil;
38using keyple::core::util::cpp::exception::IllegalArgumentException;
39using keyple::core::util::cpp::exception::IllegalStateException;
40using keypop::calypso::card::transaction::CryptoException;
41using keypop::calypso::card::transaction::InvalidCertificateException;
42using keypop::calypso::crypto::asymmetric::AsymmetricCryptoException;
43using keypop::calypso::crypto::asymmetric::certificate::
44 CertificateValidationException;
45using keypop::calypso::crypto::asymmetric::certificate::spi::CaCertificateSpi;
46using keypop::calypso::crypto::asymmetric::certificate::spi::PcaCertificateSpi;
47
48const std::string
49 AsymmetricCryptoSecuritySettingAdapter::MSG_INVALID_CERTIFICATE
50 = "Invalid certificate";
51const std::string
52 AsymmetricCryptoSecuritySettingAdapter ::MSG_FAILED_TO_CHECK_THE_CERTIFICATE
53 = "Failed to check the certificate";
54const std::string AsymmetricCryptoSecuritySettingAdapter ::
55 MSG_A_CERTIFICATE_IS_ALREADY_REGISTERED_FOR_THE_PROVIDED_PUBLIC_KEY_REFERENCE // NOLINT
56 = "A certificate is already registered for the provided public key "
57 "reference: ";
58const std::string AsymmetricCryptoSecuritySettingAdapter ::
59 MSG_THE_ISSUER_CERTIFICATE_IS_NOT_REGISTERED
60 = "The issuer certificate is not registered: ";
61const std::string AsymmetricCryptoSecuritySettingAdapter ::
62 MSG_A_PARSER_IS_ALREADY_REGISTERED_FOR_THE_CERTIFICATE_TYPE
63 = "A parser is already registered for the certificate type ";
64
65AsymmetricCryptoSecuritySettingAdapter::AsymmetricCryptoSecuritySettingAdapter(
66 std::shared_ptr<AsymmetricCryptoCardTransactionManagerFactorySpi>
67 cryptoCardTransactionManagerFactorySpi)
68: mCryptoCardTransactionManagerFactorySpi(
69 cryptoCardTransactionManagerFactorySpi)
70{
71}
72
73std::shared_ptr<AsymmetricCryptoCardTransactionManagerFactorySpi>
74AsymmetricCryptoSecuritySettingAdapter ::
75 getCryptoCardTransactionManagerFactorySpi() const
76{
77 return mCryptoCardTransactionManagerFactorySpi;
78}
79
80AsymmetricCryptoSecuritySetting&
81AsymmetricCryptoSecuritySettingAdapter::addPcaCertificate(
82 std::shared_ptr<PcaCertificate> pcaCertificate)
83{
84 Assert::getInstance().notNull(pcaCertificate, "pcaCertificate");
85
86 const auto pcaCertificateSpi(
87 std::dynamic_pointer_cast<PcaCertificateSpi>(pcaCertificate));
88 if (!pcaCertificateSpi) {
89 std::string certificateName = "null";
90 if (pcaCertificate.get()) {
91 const auto& r = *pcaCertificate.get();
92 certificateName = typeid(r).name();
93 }
94
95 throw IllegalArgumentException(
96 std::string("Cannot cast 'pcaCertificate' to PcaCertificateSpi.")
97 + " Actual type: " + certificateName);
98 }
99
100 /* Check certificate and get content */
101 std::shared_ptr<CaCertificateContentSpi> certificateContent;
102 try {
103 certificateContent = pcaCertificateSpi->checkCertificateAndGetContent();
104
105 } catch (const CertificateValidationException& e) {
106 throw InvalidCertificateException(MSG_INVALID_CERTIFICATE, e);
107
108 } catch (const AsymmetricCryptoException& e) {
109 throw CryptoException(MSG_FAILED_TO_CHECK_THE_CERTIFICATE, e);
110 }
111
112 // Save the certificate content into the store
113 const std::string pcaKeyRef(
114 HexUtil::toHex(certificateContent->getPublicKeyReference()));
115 if (mCaCertificates.count(pcaKeyRef)) {
116 throw IllegalStateException(
117 MSG_A_CERTIFICATE_IS_ALREADY_REGISTERED_FOR_THE_PROVIDED_PUBLIC_KEY_REFERENCE // NOLINT
118 + pcaKeyRef);
119 }
120 mCaCertificates.insert({pcaKeyRef, certificateContent});
121
122 return *this;
123}
124
125AsymmetricCryptoSecuritySetting&
126AsymmetricCryptoSecuritySettingAdapter::addCaCertificate(
127 std::shared_ptr<CaCertificate> caCertificate)
128{
129 Assert::getInstance().notNull(caCertificate, "caCertificate");
130
131 const auto caCertificateSpi(
132 std::dynamic_pointer_cast<CaCertificateSpi>(caCertificate));
133 if (!caCertificateSpi) {
134 std::string certificateName = "null";
135 if (caCertificateSpi.get()) {
136 const auto& r = *caCertificateSpi.get();
137 certificateName = typeid(r).name();
138 }
139
140 throw IllegalArgumentException(
141 "Cannot cast 'caCertificate' to CaCertificateSpi. Actual type: "
142 + certificateName);
143 }
144
145 /* Get the issuer public key reference */
146 const std::string issuerKeyRef
147 = HexUtil::toHex(caCertificateSpi->getIssuerPublicKeyReference());
148
149 /* Search the issuer certificate */
150 std::shared_ptr<CaCertificateContentSpi> issuerCertificateContent
151 = mCaCertificates.count(issuerKeyRef) ? mCaCertificates[issuerKeyRef]
152 : nullptr;
153 if (issuerCertificateContent == nullptr) {
154 throw IllegalStateException(
155 MSG_THE_ISSUER_CERTIFICATE_IS_NOT_REGISTERED + issuerKeyRef);
156 }
157
158 /* Check the CA certificate using the issuer's certificate content */
159 std::shared_ptr<CaCertificateContentSpi> caCertificateContent;
160 try {
161 caCertificateContent = caCertificateSpi->checkCertificateAndGetContent(
162 issuerCertificateContent);
163
164 } catch (const CertificateValidationException& e) {
165 throw InvalidCertificateException(MSG_INVALID_CERTIFICATE, e);
166
167 } catch (const AsymmetricCryptoException& e) {
168 throw CryptoException(MSG_FAILED_TO_CHECK_THE_CERTIFICATE, e);
169 }
170
171 /* Save the certificate content into the store */
172 const std::string caKeyRef
173 = HexUtil::toHex(caCertificateContent->getPublicKeyReference());
174 if (mCaCertificates.count(caKeyRef)) {
175 throw IllegalStateException(
176 MSG_A_CERTIFICATE_IS_ALREADY_REGISTERED_FOR_THE_PROVIDED_PUBLIC_KEY_REFERENCE // NOLINT
177 + caKeyRef);
178 }
179
180 mCaCertificates.insert({caKeyRef, caCertificateContent});
181
182 return *this;
183}
184
185AsymmetricCryptoSecuritySetting&
186AsymmetricCryptoSecuritySettingAdapter::addCaCertificateParser(
187 std::shared_ptr<CaCertificateParser> caCertificateParser)
188{
189 Assert::getInstance().notNull(caCertificateParser, "caCertificateParser");
190
191 auto caCertificateParserSpi(
192 std::dynamic_pointer_cast<CaCertificateParserSpi>(caCertificateParser));
193 if (!caCertificateParserSpi) {
194 std::string certificateName = "null";
195 if (caCertificateParserSpi.get()) {
196 const auto& r = *caCertificateParserSpi.get();
197 certificateName = typeid(r).name();
198 }
199
200 throw IllegalArgumentException(
201 std::string("Cannot cast 'caCertificateParser' to ")
202 + "CaCertificateParserSpi. Actual type: " + certificateName);
203 }
204
205 /* Save the parser into the store */
206 const uint8_t certificateType
207 = caCertificateParserSpi->getCertificateType();
208 if (mCaCertificateParsers.count(certificateType)) {
209 throw IllegalStateException(
210 MSG_A_PARSER_IS_ALREADY_REGISTERED_FOR_THE_CERTIFICATE_TYPE
211 + HexUtil::toHex(certificateType));
212 }
213
214 mCaCertificateParsers.insert({certificateType, caCertificateParserSpi});
215
216 return *this;
217}
218
219AsymmetricCryptoSecuritySetting&
220AsymmetricCryptoSecuritySettingAdapter::addCardCertificateParser(
221 std::shared_ptr<CardCertificateParser> cardCertificateParser)
222{
223 Assert::getInstance().notNull(
224 cardCertificateParser, "cardCertificateParser");
225
226 auto cardCertificateParserSpi(
227 std::dynamic_pointer_cast<CardCertificateParserSpi>(
228 cardCertificateParser));
229 if (!cardCertificateParserSpi) {
230 std::string certificateName = "null";
231 if (cardCertificateParserSpi.get()) {
232 const auto& r = *cardCertificateParserSpi.get();
233 certificateName = typeid(r).name();
234 }
235
236 throw IllegalArgumentException(
237 std::string("Cannot cast 'cardCertificateParser' to ")
238 + "CardCertificateParserSpi. Actual type: " + certificateName);
239 }
240
241 /* Save the parser into the store */
242 const std::uint8_t certificateType
243 = cardCertificateParserSpi->getCertificateType();
244 if (mCardCertificateParsers.count(certificateType)) {
245 throw IllegalStateException(
246 MSG_A_PARSER_IS_ALREADY_REGISTERED_FOR_THE_CERTIFICATE_TYPE
247 + HexUtil::toHex(certificateType));
248 }
249
250 mCardCertificateParsers.insert({certificateType, cardCertificateParserSpi});
251
252 return *this;
253}
254
255std::shared_ptr<CaCertificateContentSpi>
256AsymmetricCryptoSecuritySettingAdapter::getCaCertificate(
257 const std::vector<std::uint8_t>& publicKeyReference)
258{
259 const std::string ref = HexUtil::toHex(publicKeyReference);
260 return mCaCertificates.count(ref) ? mCaCertificates[ref] : nullptr;
261}
262
263std::shared_ptr<CaCertificateParserSpi>
264AsymmetricCryptoSecuritySettingAdapter::getCaCertificateParser(
265 std::uint8_t certificateType)
266{
267 return mCaCertificateParsers.count(certificateType)
268 ? mCaCertificateParsers[certificateType]
269 : nullptr;
270}
271
272std::shared_ptr<CardCertificateParserSpi>
273AsymmetricCryptoSecuritySettingAdapter::getCardCertificateParser(
274 std::uint8_t certificateType)
275{
276 return mCardCertificateParsers.count(certificateType)
277 ? mCardCertificateParsers[certificateType]
278 : nullptr;
279}
280
281} /* namespace calypso */
282} /* namespace card */
283} /* namespace keyple */