blob: 1e01dc04bcf5a65ac7cebd96f0dfba05e2463609 [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"
22#include "logging.hpp"
Zhiyi Zhanga9bda732017-05-20 22:58:55 -070023#include "challenge-module.hpp"
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070024#include "crypto-support/enc-tlv.hpp"
Suyong Won19fba4d2020-05-09 13:39:46 -070025#include "protocol-detail/info.hpp"
26#include "protocol-detail/probe.hpp"
27#include "protocol-detail/new.hpp"
28#include "protocol-detail/challenge.hpp"
tylerliu182bc532020-09-25 01:54:45 -070029#include "protocol-detail/revoke.hpp"
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +080030#include <ndn-cxx/util/io.hpp>
Zhiyi Zhang23564c82017-03-01 10:22:22 -080031#include <ndn-cxx/security/signing-helpers.hpp>
32#include <ndn-cxx/security/verification-helpers.hpp>
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070033#include <ndn-cxx/util/random.hpp>
34#include <ndn-cxx/security/transform/base64-encode.hpp>
35#include <ndn-cxx/security/transform/buffer-source.hpp>
36#include <ndn-cxx/security/transform/stream-sink.hpp>
Zhiyi Zhang23564c82017-03-01 10:22:22 -080037
38namespace ndn {
39namespace ndncert {
40
41_LOG_INIT(ndncert.client);
42
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070043ClientModule::ClientModule(security::v2::KeyChain& keyChain)
44 : m_keyChain(keyChain)
Zhiyi Zhang23564c82017-03-01 10:22:22 -080045{
46}
47
Zhiyi Zhangad9e04f2020-03-27 12:04:31 -070048ClientModule::~ClientModule()
49{
50 endSession();
51}
Davide Pesavento08994782018-01-22 12:13:41 -050052
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070053shared_ptr<Interest>
swa77020643ac2020-03-26 02:24:45 -070054ClientModule::generateInfoInterest(const Name& caName)
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +080055{
56 Name interestName = caName;
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070057 if (readString(caName.at(-1)) != "CA")
58 interestName.append("CA");
swa77020643ac2020-03-26 02:24:45 -070059 interestName.append("INFO");
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070060 auto interest = make_shared<Interest>(interestName);
61 interest->setMustBeFresh(true);
62 interest->setCanBePrefix(false);
63 return interest;
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +080064}
65
Zhiyi Zhangcaab5462019-10-18 13:41:02 -070066bool
Suyong Won19fba4d2020-05-09 13:39:46 -070067ClientModule::verifyInfoResponse(const Data& reply)
Zhiyi Zhangcaab5462019-10-18 13:41:02 -070068{
69 // parse the ca item
Suyong Won19fba4d2020-05-09 13:39:46 -070070 auto caItem = INFO::decodeClientConfigFromContent(reply.getContent());
Zhiyi Zhangcaab5462019-10-18 13:41:02 -070071
72 // verify the probe Data's sig
73 if (!security::verifySignature(reply, caItem.m_anchor)) {
Suyong Won256c9062020-05-11 02:45:56 -070074 _LOG_ERROR("Cannot verify data signature from " << m_ca.m_caPrefix.toUri());
Zhiyi Zhangcaab5462019-10-18 13:41:02 -070075 return false;
76 }
77 return true;
78}
79
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +080080void
Suyong Won19fba4d2020-05-09 13:39:46 -070081ClientModule::addCaFromInfoResponse(const Data& reply)
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +080082{
Suyong Won57462ca2020-05-05 22:20:09 -070083 const Block& contentBlock = reply.getContent();
84
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070085 // parse the ca item
Suyong Won19fba4d2020-05-09 13:39:46 -070086 auto caItem = INFO::decodeClientConfigFromContent(contentBlock);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +080087
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070088 // update the local config
89 bool findItem = false;
90 for (auto& item : m_config.m_caItems) {
Suyong Won256c9062020-05-11 02:45:56 -070091 if (item.m_caPrefix == caItem.m_caPrefix) {
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070092 findItem = true;
93 item = caItem;
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +080094 }
95 }
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070096 if (!findItem) {
97 m_config.m_caItems.push_back(caItem);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +080098 }
Zhiyi Zhang23564c82017-03-01 10:22:22 -080099}
100
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700101shared_ptr<Interest>
102ClientModule::generateProbeInterest(const ClientCaItem& ca, const std::string& probeInfo)
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800103{
Suyong Won256c9062020-05-11 02:45:56 -0700104 Name interestName = ca.m_caPrefix;
swa770de007bc2020-03-24 21:26:21 -0700105 interestName.append("CA").append("PROBE");
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700106 auto interest = make_shared<Interest>(interestName);
107 interest->setMustBeFresh(true);
108 interest->setCanBePrefix(false);
Suyong Won19fba4d2020-05-09 13:39:46 -0700109 interest->setApplicationParameters(
110 PROBE::encodeApplicationParametersFromProbeInfo(ca, probeInfo)
111 );
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700112
113 // update local state
114 m_ca = ca;
115 return interest;
116}
117
118void
119ClientModule::onProbeResponse(const Data& reply)
120{
121 if (!security::verifySignature(reply, m_ca.m_anchor)) {
Suyong Won256c9062020-05-11 02:45:56 -0700122 _LOG_ERROR("Cannot verify data signature from " << m_ca.m_caPrefix.toUri());
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700123 return;
124 }
Suyong Won19fba4d2020-05-09 13:39:46 -0700125
126 auto contentTLV = reply.getContent();
Suyong Won44d0cce2020-05-10 04:07:43 -0700127 contentTLV.parse();
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700128
129 // read the available name and put it into the state
Suyong Won19fba4d2020-05-09 13:39:46 -0700130 if (contentTLV.get(tlv_probe_response).hasValue()) {
Suyong Wonb29e0da2020-05-12 01:59:15 -0700131 Block probeResponseBlock = contentTLV.get(tlv_probe_response);
132 probeResponseBlock.parse();
133 m_identityName.wireDecode(probeResponseBlock.get(tlv::Name));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700134 }
Zhiyi Zhang781a5602019-06-26 19:05:04 -0700135 else {
136 NDN_LOG_TRACE("The JSON_CA_NAME is empty.");
137 }
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700138}
139
140shared_ptr<Interest>
141ClientModule::generateNewInterest(const time::system_clock::TimePoint& notBefore,
142 const time::system_clock::TimePoint& notAfter,
Zhiyi Zhang5f749a22019-06-12 17:02:33 -0700143 const Name& identityName, const shared_ptr<Data>& probeToken)
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700144{
145 // Name requestedName = identityName;
146 if (!identityName.empty()) { // if identityName is not empty, find the corresponding CA
147 bool findCa = false;
148 for (const auto& caItem : m_config.m_caItems) {
Suyong Won256c9062020-05-11 02:45:56 -0700149 if (caItem.m_caPrefix.isPrefixOf(identityName)) {
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700150 m_ca = caItem;
151 findCa = true;
152 }
153 }
154 if (!findCa) { // if cannot find, cannot proceed
155 return nullptr;
156 }
157 m_identityName = identityName;
158 }
159 else { // if identityName is empty, check m_identityName or generate a random name
160 if (!m_identityName.empty()) {
161 // do nothing
162 }
163 else {
Zhiyi Zhang781a5602019-06-26 19:05:04 -0700164 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 -0700165 auto id = std::to_string(random::generateSecureWord64());
Suyong Won256c9062020-05-11 02:45:56 -0700166 m_identityName = m_ca.m_caPrefix;
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700167 m_identityName.append(id);
168 }
169 }
170
171 // generate a newly key pair or use an existing key
Zhiyi Zhang10130782018-02-01 18:28:49 -0800172 const auto& pib = m_keyChain.getPib();
Zhiyi Zhangad9e04f2020-03-27 12:04:31 -0700173 security::pib::Identity identity;
Zhiyi Zhang10130782018-02-01 18:28:49 -0800174 try {
Zhiyi Zhangad9e04f2020-03-27 12:04:31 -0700175 identity = pib.getIdentity(m_identityName);
Zhiyi Zhang10130782018-02-01 18:28:49 -0800176 }
177 catch (const security::Pib::Error& e) {
Zhiyi Zhangad9e04f2020-03-27 12:04:31 -0700178 identity = m_keyChain.createIdentity(m_identityName);
179 m_isNewlyCreatedIdentity = true;
180 m_isNewlyCreatedKey = true;
181 }
182 try {
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700183 m_key = identity.getDefaultKey();
Zhiyi Zhang10130782018-02-01 18:28:49 -0800184 }
Zhiyi Zhangad9e04f2020-03-27 12:04:31 -0700185 catch (const security::Pib::Error& e) {
186 m_key = m_keyChain.createKey(identity);
187 m_isNewlyCreatedKey = true;
188 }
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800189
190 // generate certificate request
191 security::v2::Certificate certRequest;
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700192 certRequest.setName(Name(m_key.getName()).append("cert-request").appendVersion());
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800193 certRequest.setContentType(tlv::ContentType_Key);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700194 certRequest.setContent(m_key.getPublicKey().data(), m_key.getPublicKey().size());
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800195 SignatureInfo signatureInfo;
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700196 signatureInfo.setValidityPeriod(security::ValidityPeriod(notBefore, notAfter));
197 m_keyChain.sign(certRequest, signingByKey(m_key.getName()).setSignatureInfo(signatureInfo));
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800198
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700199 // generate Interest packet
Suyong Won256c9062020-05-11 02:45:56 -0700200 Name interestName = m_ca.m_caPrefix;
swa770de007bc2020-03-24 21:26:21 -0700201 interestName.append("CA").append("NEW");
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700202 auto interest = make_shared<Interest>(interestName);
203 interest->setMustBeFresh(true);
204 interest->setCanBePrefix(false);
Suyong Won19fba4d2020-05-09 13:39:46 -0700205 interest->setApplicationParameters(
206 NEW::encodeApplicationParameters(m_ecdh.getBase64PubKey(), certRequest, probeToken)
207 );
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800208
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700209 // sign the Interest packet
210 m_keyChain.sign(*interest, signingByKey(m_key.getName()));
211 return interest;
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800212}
213
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700214std::list<std::string>
215ClientModule::onNewResponse(const Data& reply)
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800216{
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700217 if (!security::verifySignature(reply, m_ca.m_anchor)) {
Suyong Won256c9062020-05-11 02:45:56 -0700218 _LOG_ERROR("Cannot verify data signature from " << m_ca.m_caPrefix.toUri());
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700219 return std::list<std::string>();
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800220 }
Suyong Won19fba4d2020-05-09 13:39:46 -0700221 auto contentTLV = reply.getContent();
Suyong Won44d0cce2020-05-10 04:07:43 -0700222 contentTLV.parse();
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800223
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700224 // ECDH
Suyong Won19fba4d2020-05-09 13:39:46 -0700225 const auto& peerKeyBase64Str = readString(contentTLV.get(tlv_ecdh_pub));
226 const auto& saltStr = readString(contentTLV.get(tlv_salt));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700227 uint64_t saltInt = std::stoull(saltStr);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700228 m_ecdh.deriveSecret(peerKeyBase64Str);
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800229
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700230 // HKDF
Zhiyi Zhang36706832019-07-04 21:33:03 -0700231 hkdf(m_ecdh.context->sharedSecret, m_ecdh.context->sharedSecretLen,
232 (uint8_t*)&saltInt, sizeof(saltInt), m_aesKey, sizeof(m_aesKey));
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800233
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700234 // update state
Suyong Won19fba4d2020-05-09 13:39:46 -0700235 m_status = readNonNegativeInteger(contentTLV.get(tlv_status));
236 m_requestId = readString(contentTLV.get(tlv_request_id));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700237 m_challengeList.clear();
Suyong Won19fba4d2020-05-09 13:39:46 -0700238 for (auto const& element : contentTLV.elements()) {
239 if (element.type() == tlv_challenge) {
240 m_challengeList.push_back(readString(element));
241 }
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800242 }
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700243 return m_challengeList;
244}
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800245
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700246shared_ptr<Interest>
tylerliu182bc532020-09-25 01:54:45 -0700247ClientModule::generateRevokeInterest(const security::v2::Certificate& certificate)
248{
249 // Name requestedName = identityName;
250 bool findCa = false;
251 for (const auto& caItem : m_config.m_caItems) {
252 if (caItem.m_caName.isPrefixOf(certificate.getName())) {
253 m_ca = caItem;
254 findCa = true;
255 }
256 }
257 if (!findCa) { // if cannot find, cannot proceed
258 _LOG_TRACE("Cannot find corresponding CA for the certificate.");
259 return nullptr;
260 }
261
262 // generate Interest packet
263 Name interestName = m_ca.m_caPrefix;
264 interestName.append("CA").append("REVOKE");
265 auto interest = make_shared<Interest>(interestName);
266 interest->setMustBeFresh(true);
267 interest->setCanBePrefix(false);
268 interest->setApplicationParameters(
269 REVOKE::encodeApplicationParameters(m_ecdh.getBase64PubKey(), certificate)
270 );
271
272 // return the Interest packet
273 return interest;
274}
275
276std::list<std::string>
277ClientModule::onRevokeResponse(const Data& reply)
278{
279 if (!security::verifySignature(reply, m_ca.m_anchor)) {
280 _LOG_ERROR("Cannot verify data signature from " << m_ca.m_caName.toUri());
281 return std::list<std::string>();
282 }
283 auto contentTLV = reply.getContent();
284 contentTLV.parse();
285
286 // ECDH
287 const auto& peerKeyBase64Str = readString(contentTLV.get(tlv_ecdh_pub));
288 const auto& saltStr = readString(contentTLV.get(tlv_salt));
289 uint64_t saltInt = std::stoull(saltStr);
290 m_ecdh.deriveSecret(peerKeyBase64Str);
291
292 // HKDF
293 hkdf(m_ecdh.context->sharedSecret, m_ecdh.context->sharedSecretLen,
294 (uint8_t*)&saltInt, sizeof(saltInt), m_aesKey, sizeof(m_aesKey));
295
296 // update state
297 m_status = readNonNegativeInteger(contentTLV.get(tlv_status));
298 m_requestId = readString(contentTLV.get(tlv_request_id));
299 m_challengeList.clear();
300 for (auto const& element : contentTLV.elements()) {
301 if (element.type() == tlv_challenge) {
302 m_challengeList.push_back(readString(element));
303 }
304 }
305 return m_challengeList;
306}
307
308shared_ptr<Interest>
Suyong Won19fba4d2020-05-09 13:39:46 -0700309ClientModule::generateChallengeInterest(const Block& challengeRequest)
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700310{
Suyong Won44d0cce2020-05-10 04:07:43 -0700311 challengeRequest.parse();
Suyong Won19fba4d2020-05-09 13:39:46 -0700312 m_challengeType = readString(challengeRequest.get(tlv_selected_challenge));
Suyong Won44d0cce2020-05-10 04:07:43 -0700313
Suyong Won256c9062020-05-11 02:45:56 -0700314 Name interestName = m_ca.m_caPrefix;
swa770de007bc2020-03-24 21:26:21 -0700315 interestName.append("CA").append("CHALLENGE").append(m_requestId);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700316 auto interest = make_shared<Interest>(interestName);
317 interest->setMustBeFresh(true);
318 interest->setCanBePrefix(false);
319
320 // encrypt the Interest parameters
Suyong Won7968f7a2020-05-12 01:01:25 -0700321 auto paramBlock = encodeBlockWithAesGcm128(tlv::ApplicationParameters, m_aesKey,
322 challengeRequest.value(), challengeRequest.value_size(), (const uint8_t*)"test", strlen("test"));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700323 interest->setApplicationParameters(paramBlock);
324
325 m_keyChain.sign(*interest, signingByKey(m_key.getName()));
326 return interest;
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800327}
328
329void
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700330ClientModule::onChallengeResponse(const Data& reply)
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800331{
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700332 if (!security::verifySignature(reply, m_ca.m_anchor)) {
Suyong Won256c9062020-05-11 02:45:56 -0700333 _LOG_ERROR("Cannot verify data signature from " << m_ca.m_caPrefix.toUri());
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800334 return;
335 }
Zhiyi Zhangb8cb0472020-05-05 20:55:05 -0700336 auto result = decodeBlockWithAesGcm128(reply.getContent(), m_aesKey, (const uint8_t*)"test", strlen("test"));
Suyong Won19fba4d2020-05-09 13:39:46 -0700337
Suyong Won44d0cce2020-05-10 04:07:43 -0700338 Block contentTLV = makeBinaryBlock(tlv_encrypted_payload, result.data(), result.size());
339 contentTLV.parse();
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800340
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700341 // update state
Suyong Won19fba4d2020-05-09 13:39:46 -0700342 m_status = readNonNegativeInteger(contentTLV.get(tlv_status));
343 m_challengeStatus = readString(contentTLV.get(tlv_challenge_status));
344 m_remainingTries = readNonNegativeInteger(contentTLV.get(tlv_remaining_tries));
345 m_freshBefore = time::system_clock::now() +
346 time::seconds(readNonNegativeInteger(contentTLV.get(tlv_remaining_time)));
347
Suyong Won7968f7a2020-05-12 01:01:25 -0700348 if (contentTLV.find(tlv_issued_cert_name) != contentTLV.elements_end()) {
349 Block issuedCertNameBlock = contentTLV.get(tlv_issued_cert_name);
350 issuedCertNameBlock.parse();
351 m_issuedCertName.wireDecode(issuedCertNameBlock.get(tlv::Name));
352 }
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700353}
Zhiyi Zhange30eb352017-04-13 15:26:14 -0700354
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700355shared_ptr<Interest>
356ClientModule::generateDownloadInterest()
357{
Suyong Won256c9062020-05-11 02:45:56 -0700358 Name interestName = m_ca.m_caPrefix;
swa770de007bc2020-03-24 21:26:21 -0700359 interestName.append("CA").append("DOWNLOAD").append(m_requestId);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700360 auto interest = make_shared<Interest>(interestName);
361 interest->setMustBeFresh(true);
362 interest->setCanBePrefix(false);
363 return interest;
364}
Zhiyi Zhange30eb352017-04-13 15:26:14 -0700365
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700366shared_ptr<Interest>
367ClientModule::generateCertFetchInterest()
368{
swa770cf1d8f72020-04-21 23:12:39 -0700369 Name interestName = m_issuedCertName;
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700370 auto interest = make_shared<Interest>(interestName);
371 interest->setMustBeFresh(true);
372 interest->setCanBePrefix(false);
373 return interest;
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800374}
375
swa770cf1d8f72020-04-21 23:12:39 -0700376void
377ClientModule::onCertFetchResponse(const Data& reply)
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800378{
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800379 try {
380 security::v2::Certificate cert(reply.getContent().blockFromValue());
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700381 m_keyChain.addCertificate(m_key, cert);
swa770cf1d8f72020-04-21 23:12:39 -0700382 _LOG_TRACE("Fetched and installed the cert " << cert.getName());
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800383 }
384 catch (const std::exception& e) {
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700385 _LOG_ERROR("Cannot add replied certificate into the keychain " << e.what());
Zhiyi Zhangef6b36a2020-09-22 21:20:59 -0700386 return;
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800387 }
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800388}
389
Zhiyi Zhangef6b36a2020-09-22 21:20:59 -0700390void
391ClientModule::endSession()
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800392{
Zhiyi Zhangef6b36a2020-09-22 21:20:59 -0700393 if (getApplicationStatus() == STATUS_SUCCESS || getApplicationStatus() == STATUS_ENDED) {
394 return;
395 }
396 if (m_isNewlyCreatedIdentity) {
397 // put the identity into the if scope is because it may cause an error
398 // outside since when endSession is called, identity may not have been created yet.
399 auto identity = m_keyChain.getPib().getIdentity(m_identityName);
400 m_keyChain.deleteIdentity(identity);
401 }
402 else if (m_isNewlyCreatedKey) {
403 auto identity = m_keyChain.getPib().getIdentity(m_identityName);
404 m_keyChain.deleteKey(identity, m_key);
405 }
406 m_status = STATUS_ENDED;
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800407}
408
Zhiyi Zhangef6b36a2020-09-22 21:20:59 -0700409
Zhiyi Zhang547c8512019-06-18 23:46:14 -0700410std::vector<std::string>
411ClientModule::parseProbeComponents(const std::string& probe)
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700412{
Zhiyi Zhang547c8512019-06-18 23:46:14 -0700413 std::vector<std::string> components;
Yufeng Zhang424d0362019-06-12 16:48:27 -0700414 std::string delimiter = ":";
415 size_t last = 0;
416 size_t next = 0;
Zhiyi Zhang547c8512019-06-18 23:46:14 -0700417 while ((next = probe.find(delimiter, last)) != std::string::npos) {
418 components.push_back(probe.substr(last, next - last));
419 last = next + 1;
420 }
421 components.push_back(probe.substr(last));
422 return components;
423}
Yufeng Zhang424d0362019-06-12 16:48:27 -0700424
Zhiyi Zhang23564c82017-03-01 10:22:22 -0800425} // namespace ndncert
426} // namespace ndn