blob: 46405bb68606b61b3d3dd76f3d7a791ea691dadf [file] [log] [blame]
Zhiyi Zhang23564c82017-03-01 10:22:22 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Zhiyi Zhangad9e04f2020-03-27 12:04:31 -07003 * Copyright (c) 2017-2020, Regents of the University of California.
Zhiyi Zhang23564c82017-03-01 10:22:22 -08004 *
5 * This file is part of ndncert, a certificate management system based on NDN.
6 *
7 * ndncert is free software: you can redistribute it and/or modify it under the terms
8 * of the GNU General Public License as published by the Free Software Foundation, either
9 * version 3 of the License, or (at your option) any later version.
10 *
11 * ndncert is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License along with
16 * ndncert, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * See AUTHORS.md for complete list of ndncert authors and contributors.
19 */
20
21#include "client-module.hpp"
Zhiyi Zhang48f23782020-09-28 12:11:24 -070022
Zhiyi Zhang23564c82017-03-01 10:22:22 -080023#include <ndn-cxx/security/signing-helpers.hpp>
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070024#include <ndn-cxx/security/transform/base64-encode.hpp>
25#include <ndn-cxx/security/transform/buffer-source.hpp>
26#include <ndn-cxx/security/transform/stream-sink.hpp>
Zhiyi Zhang48f23782020-09-28 12:11:24 -070027#include <ndn-cxx/security/verification-helpers.hpp>
28#include <ndn-cxx/util/io.hpp>
29#include <ndn-cxx/util/random.hpp>
30
31#include "challenge-module.hpp"
32#include "crypto-support/enc-tlv.hpp"
Zhiyi Zhang48f23782020-09-28 12:11:24 -070033#include "protocol-detail/challenge.hpp"
34#include "protocol-detail/info.hpp"
35#include "protocol-detail/new.hpp"
36#include "protocol-detail/probe.hpp"
37#include "protocol-detail/revoke.hpp"
tylerliu36d97f52020-09-30 22:32:54 -070038#include "protocol-detail/error.hpp"
39#include "ndncert-common.hpp"
Zhiyi Zhang23564c82017-03-01 10:22:22 -080040
41namespace ndn {
42namespace ndncert {
43
44_LOG_INIT(ndncert.client);
45
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070046ClientModule::ClientModule(security::v2::KeyChain& keyChain)
Zhiyi Zhang48f23782020-09-28 12:11:24 -070047 : m_keyChain(keyChain)
Zhiyi Zhang23564c82017-03-01 10:22:22 -080048{
49}
50
Zhiyi Zhangad9e04f2020-03-27 12:04:31 -070051ClientModule::~ClientModule()
52{
53 endSession();
54}
Davide Pesavento08994782018-01-22 12:13:41 -050055
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070056shared_ptr<Interest>
swa77020643ac2020-03-26 02:24:45 -070057ClientModule::generateInfoInterest(const Name& caName)
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +080058{
59 Name interestName = caName;
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070060 if (readString(caName.at(-1)) != "CA")
61 interestName.append("CA");
swa77020643ac2020-03-26 02:24:45 -070062 interestName.append("INFO");
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070063 auto interest = make_shared<Interest>(interestName);
64 interest->setMustBeFresh(true);
65 interest->setCanBePrefix(false);
66 return interest;
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +080067}
68
Zhiyi Zhangcaab5462019-10-18 13:41:02 -070069bool
Suyong Won19fba4d2020-05-09 13:39:46 -070070ClientModule::verifyInfoResponse(const Data& reply)
Zhiyi Zhangcaab5462019-10-18 13:41:02 -070071{
72 // parse the ca item
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -070073 auto caItem = INFO::decodeDataContent(reply.getContent());
Zhiyi Zhangcaab5462019-10-18 13:41:02 -070074
75 // verify the probe Data's sig
Zhiyi Zhang9829da92020-09-30 16:19:34 -070076 if (!security::verifySignature(reply, *caItem.m_cert)) {
Suyong Won256c9062020-05-11 02:45:56 -070077 _LOG_ERROR("Cannot verify data signature from " << m_ca.m_caPrefix.toUri());
Zhiyi Zhangcaab5462019-10-18 13:41:02 -070078 return false;
79 }
80 return true;
81}
82
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +080083void
Suyong Won19fba4d2020-05-09 13:39:46 -070084ClientModule::addCaFromInfoResponse(const Data& reply)
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +080085{
Suyong Won57462ca2020-05-05 22:20:09 -070086 const Block& contentBlock = reply.getContent();
87
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070088 // parse the ca item
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -070089 auto caItem = INFO::decodeDataContent(contentBlock);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +080090
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070091 // update the local config
92 bool findItem = false;
93 for (auto& item : m_config.m_caItems) {
Suyong Won256c9062020-05-11 02:45:56 -070094 if (item.m_caPrefix == caItem.m_caPrefix) {
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070095 findItem = true;
96 item = caItem;
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +080097 }
98 }
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070099 if (!findItem) {
100 m_config.m_caItems.push_back(caItem);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800101 }
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800102}
103
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700104shared_ptr<Interest>
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700105ClientModule::generateProbeInterest(const CaConfigItem& ca,
106 std::vector<std::tuple<std::string, std::string>>&& probeInfo)
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800107{
Suyong Won256c9062020-05-11 02:45:56 -0700108 Name interestName = ca.m_caPrefix;
swa770de007bc2020-03-24 21:26:21 -0700109 interestName.append("CA").append("PROBE");
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700110 auto interest = make_shared<Interest>(interestName);
111 interest->setMustBeFresh(true);
112 interest->setCanBePrefix(false);
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700113 interest->setApplicationParameters(PROBE::encodeApplicationParameters(std::move(probeInfo)));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700114
115 // update local state
116 m_ca = ca;
117 return interest;
118}
119
120void
121ClientModule::onProbeResponse(const Data& reply)
122{
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700123 if (!security::verifySignature(reply, *m_ca.m_cert)) {
Suyong Won256c9062020-05-11 02:45:56 -0700124 _LOG_ERROR("Cannot verify data signature from " << m_ca.m_caPrefix.toUri());
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700125 return;
126 }
Suyong Won19fba4d2020-05-09 13:39:46 -0700127
tylerliu36d97f52020-09-30 22:32:54 -0700128 // error handling
129 processIfError(reply);
130
Suyong Won19fba4d2020-05-09 13:39:46 -0700131 auto contentTLV = reply.getContent();
Suyong Won44d0cce2020-05-10 04:07:43 -0700132 contentTLV.parse();
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700133
134 // read the available name and put it into the state
Suyong Won19fba4d2020-05-09 13:39:46 -0700135 if (contentTLV.get(tlv_probe_response).hasValue()) {
Suyong Wonb29e0da2020-05-12 01:59:15 -0700136 Block probeResponseBlock = contentTLV.get(tlv_probe_response);
137 probeResponseBlock.parse();
138 m_identityName.wireDecode(probeResponseBlock.get(tlv::Name));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700139 }
Zhiyi Zhang781a5602019-06-26 19:05:04 -0700140 else {
141 NDN_LOG_TRACE("The JSON_CA_NAME is empty.");
142 }
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700143}
144
145shared_ptr<Interest>
146ClientModule::generateNewInterest(const time::system_clock::TimePoint& notBefore,
147 const time::system_clock::TimePoint& notAfter,
Zhiyi Zhangb8bbc642020-09-29 14:08:26 -0700148 const Name& identityName)
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700149{
150 // Name requestedName = identityName;
Zhiyi Zhang48f23782020-09-28 12:11:24 -0700151 if (!identityName.empty()) { // if identityName is not empty, find the corresponding CA
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700152 bool findCa = false;
153 for (const auto& caItem : m_config.m_caItems) {
Suyong Won256c9062020-05-11 02:45:56 -0700154 if (caItem.m_caPrefix.isPrefixOf(identityName)) {
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700155 m_ca = caItem;
156 findCa = true;
157 }
158 }
Zhiyi Zhang48f23782020-09-28 12:11:24 -0700159 if (!findCa) { // if cannot find, cannot proceed
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700160 return nullptr;
161 }
162 m_identityName = identityName;
163 }
Zhiyi Zhang48f23782020-09-28 12:11:24 -0700164 else { // if identityName is empty, check m_identityName or generate a random name
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700165 if (!m_identityName.empty()) {
166 // do nothing
167 }
168 else {
Zhiyi Zhang781a5602019-06-26 19:05:04 -0700169 NDN_LOG_TRACE("Randomly create a new name because m_identityName is empty and the param is empty.");
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700170 auto id = std::to_string(random::generateSecureWord64());
Suyong Won256c9062020-05-11 02:45:56 -0700171 m_identityName = m_ca.m_caPrefix;
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700172 m_identityName.append(id);
173 }
174 }
175
176 // generate a newly key pair or use an existing key
Zhiyi Zhang10130782018-02-01 18:28:49 -0800177 const auto& pib = m_keyChain.getPib();
Zhiyi Zhangad9e04f2020-03-27 12:04:31 -0700178 security::pib::Identity identity;
Zhiyi Zhang10130782018-02-01 18:28:49 -0800179 try {
Zhiyi Zhangad9e04f2020-03-27 12:04:31 -0700180 identity = pib.getIdentity(m_identityName);
Zhiyi Zhang10130782018-02-01 18:28:49 -0800181 }
182 catch (const security::Pib::Error& e) {
Zhiyi Zhangad9e04f2020-03-27 12:04:31 -0700183 identity = m_keyChain.createIdentity(m_identityName);
184 m_isNewlyCreatedIdentity = true;
185 m_isNewlyCreatedKey = true;
186 }
187 try {
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700188 m_key = identity.getDefaultKey();
Zhiyi Zhang10130782018-02-01 18:28:49 -0800189 }
Zhiyi Zhangad9e04f2020-03-27 12:04:31 -0700190 catch (const security::Pib::Error& e) {
191 m_key = m_keyChain.createKey(identity);
192 m_isNewlyCreatedKey = true;
193 }
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800194
195 // generate certificate request
196 security::v2::Certificate certRequest;
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700197 certRequest.setName(Name(m_key.getName()).append("cert-request").appendVersion());
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800198 certRequest.setContentType(tlv::ContentType_Key);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700199 certRequest.setContent(m_key.getPublicKey().data(), m_key.getPublicKey().size());
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800200 SignatureInfo signatureInfo;
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700201 signatureInfo.setValidityPeriod(security::ValidityPeriod(notBefore, notAfter));
202 m_keyChain.sign(certRequest, signingByKey(m_key.getName()).setSignatureInfo(signatureInfo));
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800203
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700204 // generate Interest packet
Suyong Won256c9062020-05-11 02:45:56 -0700205 Name interestName = m_ca.m_caPrefix;
swa770de007bc2020-03-24 21:26:21 -0700206 interestName.append("CA").append("NEW");
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700207 auto interest = make_shared<Interest>(interestName);
208 interest->setMustBeFresh(true);
209 interest->setCanBePrefix(false);
Suyong Won19fba4d2020-05-09 13:39:46 -0700210 interest->setApplicationParameters(
Zhiyi Zhangb8bbc642020-09-29 14:08:26 -0700211 NEW::encodeApplicationParameters(m_ecdh.getBase64PubKey(), certRequest));
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800212
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700213 // sign the Interest packet
214 m_keyChain.sign(*interest, signingByKey(m_key.getName()));
215 return interest;
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800216}
217
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700218std::list<std::string>
tylerliu0e176c32020-09-29 11:39:46 -0700219ClientModule::onNewRenewRevokeResponse(const Data& reply)
tylerliu4a00aad2020-09-26 02:03:17 -0700220{
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700221 if (!security::verifySignature(reply, *m_ca.m_cert)) {
Suyong Won256c9062020-05-11 02:45:56 -0700222 _LOG_ERROR("Cannot verify data signature from " << m_ca.m_caPrefix.toUri());
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700223 return std::list<std::string>();
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800224 }
tylerliu36d97f52020-09-30 22:32:54 -0700225
226 // error handling
227 processIfError(reply);
228
Suyong Won19fba4d2020-05-09 13:39:46 -0700229 auto contentTLV = reply.getContent();
Suyong Won44d0cce2020-05-10 04:07:43 -0700230 contentTLV.parse();
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800231
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700232 // ECDH
Zhiyi Zhang48f23782020-09-28 12:11:24 -0700233 const auto& peerKeyBase64Str = readString(contentTLV.get(tlv_ecdh_pub));
Suyong Won19fba4d2020-05-09 13:39:46 -0700234 const auto& saltStr = readString(contentTLV.get(tlv_salt));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700235 uint64_t saltInt = std::stoull(saltStr);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700236 m_ecdh.deriveSecret(peerKeyBase64Str);
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800237
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700238 // HKDF
Zhiyi Zhang36706832019-07-04 21:33:03 -0700239 hkdf(m_ecdh.context->sharedSecret, m_ecdh.context->sharedSecretLen,
240 (uint8_t*)&saltInt, sizeof(saltInt), m_aesKey, sizeof(m_aesKey));
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800241
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700242 // update state
Zhiyi Zhang48f23782020-09-28 12:11:24 -0700243 m_status = static_cast<Status>(readNonNegativeInteger(contentTLV.get(tlv_status)));
Suyong Won19fba4d2020-05-09 13:39:46 -0700244 m_requestId = readString(contentTLV.get(tlv_request_id));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700245 m_challengeList.clear();
Suyong Won19fba4d2020-05-09 13:39:46 -0700246 for (auto const& element : contentTLV.elements()) {
247 if (element.type() == tlv_challenge) {
248 m_challengeList.push_back(readString(element));
249 }
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800250 }
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700251 return m_challengeList;
252}
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800253
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700254shared_ptr<Interest>
tylerliu182bc532020-09-25 01:54:45 -0700255ClientModule::generateRevokeInterest(const security::v2::Certificate& certificate)
256{
Zhiyi Zhang48f23782020-09-28 12:11:24 -0700257 // Name requestedName = identityName;
258 bool findCa = false;
259 for (const auto& caItem : m_config.m_caItems) {
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700260 if (caItem.m_caPrefix.isPrefixOf(certificate.getName())) {
Zhiyi Zhang48f23782020-09-28 12:11:24 -0700261 m_ca = caItem;
262 findCa = true;
tylerliu182bc532020-09-25 01:54:45 -0700263 }
Zhiyi Zhang48f23782020-09-28 12:11:24 -0700264 }
265 if (!findCa) { // if cannot find, cannot proceed
266 _LOG_TRACE("Cannot find corresponding CA for the certificate.");
267 return nullptr;
268 }
tylerliu182bc532020-09-25 01:54:45 -0700269
Zhiyi Zhang48f23782020-09-28 12:11:24 -0700270 // generate Interest packet
271 Name interestName = m_ca.m_caPrefix;
272 interestName.append("CA").append("REVOKE");
273 auto interest = make_shared<Interest>(interestName);
274 interest->setMustBeFresh(true);
275 interest->setCanBePrefix(false);
276 interest->setApplicationParameters(
277 REVOKE::encodeApplicationParameters(m_ecdh.getBase64PubKey(), certificate));
tylerliu182bc532020-09-25 01:54:45 -0700278
Zhiyi Zhang48f23782020-09-28 12:11:24 -0700279 // return the Interest packet
280 return interest;
tylerliu182bc532020-09-25 01:54:45 -0700281}
282
tylerliu182bc532020-09-25 01:54:45 -0700283shared_ptr<Interest>
Suyong Won19fba4d2020-05-09 13:39:46 -0700284ClientModule::generateChallengeInterest(const Block& challengeRequest)
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700285{
Suyong Won44d0cce2020-05-10 04:07:43 -0700286 challengeRequest.parse();
Suyong Won19fba4d2020-05-09 13:39:46 -0700287 m_challengeType = readString(challengeRequest.get(tlv_selected_challenge));
Suyong Won44d0cce2020-05-10 04:07:43 -0700288
Suyong Won256c9062020-05-11 02:45:56 -0700289 Name interestName = m_ca.m_caPrefix;
swa770de007bc2020-03-24 21:26:21 -0700290 interestName.append("CA").append("CHALLENGE").append(m_requestId);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700291 auto interest = make_shared<Interest>(interestName);
292 interest->setMustBeFresh(true);
293 interest->setCanBePrefix(false);
294
295 // encrypt the Interest parameters
Suyong Won7968f7a2020-05-12 01:01:25 -0700296 auto paramBlock = encodeBlockWithAesGcm128(tlv::ApplicationParameters, m_aesKey,
Zhiyi Zhang48f23782020-09-28 12:11:24 -0700297 challengeRequest.value(), challengeRequest.value_size(),
298 (const uint8_t*)"test", strlen("test"));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700299 interest->setApplicationParameters(paramBlock);
300
301 m_keyChain.sign(*interest, signingByKey(m_key.getName()));
302 return interest;
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800303}
304
305void
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700306ClientModule::onChallengeResponse(const Data& reply)
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800307{
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700308 if (!security::verifySignature(reply, *m_ca.m_cert)) {
Suyong Won256c9062020-05-11 02:45:56 -0700309 _LOG_ERROR("Cannot verify data signature from " << m_ca.m_caPrefix.toUri());
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800310 return;
311 }
tylerliu36d97f52020-09-30 22:32:54 -0700312
313 // error handling
314 processIfError(reply);
315
Zhiyi Zhangb8cb0472020-05-05 20:55:05 -0700316 auto result = decodeBlockWithAesGcm128(reply.getContent(), m_aesKey, (const uint8_t*)"test", strlen("test"));
Suyong Won19fba4d2020-05-09 13:39:46 -0700317
Suyong Won44d0cce2020-05-10 04:07:43 -0700318 Block contentTLV = makeBinaryBlock(tlv_encrypted_payload, result.data(), result.size());
319 contentTLV.parse();
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800320
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700321 // update state
Zhiyi Zhang48f23782020-09-28 12:11:24 -0700322 m_status = static_cast<Status>(readNonNegativeInteger(contentTLV.get(tlv_status)));
Suyong Won19fba4d2020-05-09 13:39:46 -0700323 m_challengeStatus = readString(contentTLV.get(tlv_challenge_status));
324 m_remainingTries = readNonNegativeInteger(contentTLV.get(tlv_remaining_tries));
325 m_freshBefore = time::system_clock::now() +
326 time::seconds(readNonNegativeInteger(contentTLV.get(tlv_remaining_time)));
327
Suyong Won7968f7a2020-05-12 01:01:25 -0700328 if (contentTLV.find(tlv_issued_cert_name) != contentTLV.elements_end()) {
329 Block issuedCertNameBlock = contentTLV.get(tlv_issued_cert_name);
330 issuedCertNameBlock.parse();
331 m_issuedCertName.wireDecode(issuedCertNameBlock.get(tlv::Name));
332 }
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700333}
Zhiyi Zhange30eb352017-04-13 15:26:14 -0700334
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700335shared_ptr<Interest>
336ClientModule::generateDownloadInterest()
337{
Suyong Won256c9062020-05-11 02:45:56 -0700338 Name interestName = m_ca.m_caPrefix;
swa770de007bc2020-03-24 21:26:21 -0700339 interestName.append("CA").append("DOWNLOAD").append(m_requestId);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700340 auto interest = make_shared<Interest>(interestName);
341 interest->setMustBeFresh(true);
342 interest->setCanBePrefix(false);
343 return interest;
344}
Zhiyi Zhange30eb352017-04-13 15:26:14 -0700345
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700346shared_ptr<Interest>
347ClientModule::generateCertFetchInterest()
348{
swa770cf1d8f72020-04-21 23:12:39 -0700349 Name interestName = m_issuedCertName;
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700350 auto interest = make_shared<Interest>(interestName);
351 interest->setMustBeFresh(true);
352 interest->setCanBePrefix(false);
353 return interest;
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800354}
355
swa770cf1d8f72020-04-21 23:12:39 -0700356void
357ClientModule::onCertFetchResponse(const Data& reply)
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800358{
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800359 try {
360 security::v2::Certificate cert(reply.getContent().blockFromValue());
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700361 m_keyChain.addCertificate(m_key, cert);
swa770cf1d8f72020-04-21 23:12:39 -0700362 _LOG_TRACE("Fetched and installed the cert " << cert.getName());
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800363 }
364 catch (const std::exception& e) {
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700365 _LOG_ERROR("Cannot add replied certificate into the keychain " << e.what());
Zhiyi Zhangef6b36a2020-09-22 21:20:59 -0700366 return;
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800367 }
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800368}
369
Zhiyi Zhangef6b36a2020-09-22 21:20:59 -0700370void
371ClientModule::endSession()
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800372{
Zhiyi Zhang48f23782020-09-28 12:11:24 -0700373 if (getApplicationStatus() == Status::SUCCESS || getApplicationStatus() == Status::ENDED) {
Zhiyi Zhangef6b36a2020-09-22 21:20:59 -0700374 return;
375 }
376 if (m_isNewlyCreatedIdentity) {
377 // put the identity into the if scope is because it may cause an error
378 // outside since when endSession is called, identity may not have been created yet.
379 auto identity = m_keyChain.getPib().getIdentity(m_identityName);
380 m_keyChain.deleteIdentity(identity);
381 }
382 else if (m_isNewlyCreatedKey) {
383 auto identity = m_keyChain.getPib().getIdentity(m_identityName);
384 m_keyChain.deleteKey(identity, m_key);
385 }
Zhiyi Zhang48f23782020-09-28 12:11:24 -0700386 m_status = Status::ENDED;
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800387}
388
tylerliu36d97f52020-09-30 22:32:54 -0700389void
390ClientModule::processIfError(const Data& data)
391{
392 auto contentTLV = data.getContent();
393 if (ErrorTLV::isErrorContent(contentTLV)) {
394 try {
395 auto error = ErrorTLV::decodefromDataContent(contentTLV);
396 _LOG_ERROR("Error data returned for " << data.getName() << ": " << std::endl <<
397 "Code: " << errorCodeToString(std::get<0>(error)) << std::endl <<
398 "Info: " << std::get<1>(error) << std::endl);
399 } catch (const std::exception& e) {
400 _LOG_ERROR("Cannot parse error data content for " << data.getName());
401 return;
402 }
403 }
404}
405
Zhiyi Zhang48f23782020-09-28 12:11:24 -0700406} // namespace ndncert
407} // namespace ndn