blob: 3523d778dcb5c4e130df36b69c23f992f73f5c72 [file] [log] [blame]
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento0dc02012021-11-23 22:55:03 -05002/*
Davide Pesavento9510c912024-02-25 17:50:05 -05003 * Copyright (c) 2017-2024, Regents of the University of California.
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -07004 *
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
tylerliu4140fe82021-01-27 15:45:44 -080021#include "requester-request.hpp"
Davide Pesavento0dc02012021-11-23 22:55:03 -050022
Zhiyi Zhang84e11842020-11-19 20:03:23 -080023#include "challenge/challenge-module.hpp"
Zhiyi Zhangdc25ddf2020-10-20 14:28:55 -070024#include "detail/crypto-helpers.hpp"
Zhiyi Zhang062be6d2020-10-14 17:13:43 -070025#include "detail/challenge-encoder.hpp"
26#include "detail/error-encoder.hpp"
27#include "detail/info-encoder.hpp"
Zhiyi Zhang7cca76a2021-02-17 14:57:42 -080028#include "detail/request-encoder.hpp"
Zhiyi Zhang062be6d2020-10-14 17:13:43 -070029#include "detail/probe-encoder.hpp"
Davide Pesavento0dc02012021-11-23 22:55:03 -050030
31#include <ndn-cxx/metadata-object.hpp>
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070032#include <ndn-cxx/security/signing-helpers.hpp>
33#include <ndn-cxx/security/transform/base64-encode.hpp>
34#include <ndn-cxx/security/transform/buffer-source.hpp>
35#include <ndn-cxx/security/transform/stream-sink.hpp>
36#include <ndn-cxx/security/verification-helpers.hpp>
37#include <ndn-cxx/util/io.hpp>
Davide Pesavento9510c912024-02-25 17:50:05 -050038#include <ndn-cxx/util/logger.hpp>
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070039#include <ndn-cxx/util/random.hpp>
Davide Pesavento0dc02012021-11-23 22:55:03 -050040
tylerliu96a67e82020-10-15 13:37:12 -070041#include <boost/lexical_cast.hpp>
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070042
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040043namespace ndncert::requester {
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070044
Zhiyi Zhangd61b4a82020-10-10 15:18:43 -070045NDN_LOG_INIT(ndncert.client);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070046
Davide Pesavento0dc02012021-11-23 22:55:03 -050047std::shared_ptr<Interest>
tylerliu4140fe82021-01-27 15:45:44 -080048Request::genCaProfileDiscoveryInterest(const Name& caName)
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070049{
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070050 Name contentName = caName;
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070051 if (readString(caName.at(-1)) != "CA")
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070052 contentName.append("CA");
53 contentName.append("INFO");
Davide Pesavento0dc02012021-11-23 22:55:03 -050054 return std::make_shared<Interest>(ndn::MetadataObject::makeDiscoveryInterest(contentName));
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070055}
56
Davide Pesavento0dc02012021-11-23 22:55:03 -050057std::shared_ptr<Interest>
tylerliu4140fe82021-01-27 15:45:44 -080058Request::genCaProfileInterestFromDiscoveryResponse(const Data& reply)
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070059{
Davide Pesavento0dc02012021-11-23 22:55:03 -050060 auto metaData = ndn::MetadataObject(reply);
Davide Pesavento64d5c8f2022-03-07 22:06:22 -050061 auto interestName = metaData.getVersionedName();
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070062 interestName.appendSegment(0);
Davide Pesavento64d5c8f2022-03-07 22:06:22 -050063 return std::make_shared<Interest>(interestName);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070064}
65
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040066std::optional<CaProfile>
tylerliu4140fe82021-01-27 15:45:44 -080067Request::onCaProfileResponse(const Data& reply)
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070068{
Zhiyi Zhangf22ae242020-11-17 10:51:15 -080069 auto caItem = infotlv::decodeDataContent(reply.getContent());
Davide Pesavento0dc02012021-11-23 22:55:03 -050070 if (!ndn::security::verifySignature(reply, *caItem.cert)) {
Zhiyi Zhangd61b4a82020-10-10 15:18:43 -070071 NDN_LOG_ERROR("Cannot verify replied Data packet signature.");
tylerliu41c11532020-10-10 16:14:45 -070072 NDN_THROW(std::runtime_error("Cannot verify replied Data packet signature."));
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070073 }
74 return caItem;
75}
76
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040077std::optional<CaProfile>
tylerliu4140fe82021-01-27 15:45:44 -080078Request::onCaProfileResponseAfterRedirection(const Data& reply, const Name& caCertFullName)
Zhiyi Zhang837406d2020-10-05 22:01:31 -070079{
Zhiyi Zhangf22ae242020-11-17 10:51:15 -080080 auto caItem = infotlv::decodeDataContent(reply.getContent());
Zhiyi Zhang44c6a352020-12-14 10:57:17 -080081 auto certBlock = caItem.cert->wireEncode();
Davide Pesavento0dc02012021-11-23 22:55:03 -050082 caItem.cert = std::make_shared<Certificate>(certBlock);
Zhiyi Zhang44c6a352020-12-14 10:57:17 -080083 if (caItem.cert->getFullName() != caCertFullName) {
Zhiyi Zhangd61b4a82020-10-10 15:18:43 -070084 NDN_LOG_ERROR("Ca profile does not match the certificate information offered by the original CA.");
tylerliu41c11532020-10-10 16:14:45 -070085 NDN_THROW(std::runtime_error("Cannot verify replied Data packet signature."));
Zhiyi Zhang837406d2020-10-05 22:01:31 -070086 }
87 return onCaProfileResponse(reply);
88}
89
Davide Pesavento0dc02012021-11-23 22:55:03 -050090std::shared_ptr<Interest>
tylerliu4140fe82021-01-27 15:45:44 -080091Request::genProbeInterest(const CaProfile& ca, std::multimap<std::string, std::string>&& probeInfo)
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070092{
Zhiyi Zhang44c6a352020-12-14 10:57:17 -080093 Name interestName = ca.caPrefix;
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070094 interestName.append("CA").append("PROBE");
Davide Pesavento0dc02012021-11-23 22:55:03 -050095 auto interest = std::make_shared<Interest>(interestName);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070096 interest->setMustBeFresh(true);
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040097 interest->setApplicationParameters(probetlv::encodeApplicationParameters(probeInfo));
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070098 return interest;
99}
100
101void
tylerliu4140fe82021-01-27 15:45:44 -0800102Request::onProbeResponse(const Data& reply, const CaProfile& ca,
103 std::vector<std::pair<Name, int>>& identityNames, std::vector<Name>& otherCas)
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700104{
Davide Pesavento0dc02012021-11-23 22:55:03 -0500105 if (!ndn::security::verifySignature(reply, *ca.cert)) {
Zhiyi Zhangd61b4a82020-10-10 15:18:43 -0700106 NDN_LOG_ERROR("Cannot verify replied Data packet signature.");
tylerliu41c11532020-10-10 16:14:45 -0700107 NDN_THROW(std::runtime_error("Cannot verify replied Data packet signature."));
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700108 }
109 processIfError(reply);
Zhiyi Zhangf22ae242020-11-17 10:51:15 -0800110 probetlv::decodeDataContent(reply.getContent(), identityNames, otherCas);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700111}
112
Davide Pesavento0dc02012021-11-23 22:55:03 -0500113Request::Request(ndn::KeyChain& keyChain, const CaProfile& profile, RequestType requestType)
114 : m_caProfile(profile)
115 , m_type(requestType)
116 , m_keyChain(keyChain)
117{
118}
tylerliu4140fe82021-01-27 15:45:44 -0800119
Davide Pesavento0dc02012021-11-23 22:55:03 -0500120std::shared_ptr<Interest>
Tianyuan Yuca23bb02022-03-09 14:09:14 -0800121Request::genNewInterest(const Name& keyName,
Davide Pesavento76304d82023-08-10 23:38:06 -0400122 const time::system_clock::time_point& notBefore,
123 const time::system_clock::time_point& notAfter)
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700124{
Tianyuan Yuca23bb02022-03-09 14:09:14 -0800125 if (!m_caProfile.caPrefix.isPrefixOf(keyName)) {
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700126 return nullptr;
127 }
Tianyuan Yuca23bb02022-03-09 14:09:14 -0800128 if (keyName.empty()) {
129 return nullptr;
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700130 }
131 else {
Tianyuan Yuca23bb02022-03-09 14:09:14 -0800132 const auto& pib = m_keyChain.getPib();
133 ndn::security::pib::Identity identity;
134 m_identityName = ndn::security::extractIdentityFromKeyName(keyName);
Zhiyi Zhang6499edd2021-02-17 22:37:21 -0800135 identity = pib.getIdentity(m_identityName);
Tianyuan Yuca23bb02022-03-09 14:09:14 -0800136 m_keyPair = identity.getKey(keyName);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700137 }
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700138
139 // generate certificate request
Davide Pesavento0dc02012021-11-23 22:55:03 -0500140 Certificate certRequest;
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700141 certRequest.setName(Name(keyName).append("cert-request").appendVersion());
Zhiyi Zhang8f1ade32020-10-14 16:42:57 -0700142 certRequest.setContentType(ndn::tlv::ContentType_Key);
Davide Pesavento6f1a2ab2022-03-17 03:57:21 -0400143 certRequest.setContent(m_keyPair.getPublicKey());
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700144 SignatureInfo signatureInfo;
Davide Pesavento0dc02012021-11-23 22:55:03 -0500145 signatureInfo.setValidityPeriod(ndn::security::ValidityPeriod(notBefore, notAfter));
tylerliu4140fe82021-01-27 15:45:44 -0800146 m_keyChain.sign(certRequest, signingByKey(keyName).setSignatureInfo(signatureInfo));
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700147
148 // generate Interest packet
Zhiyi Zhang6499edd2021-02-17 22:37:21 -0800149 Name interestName = m_caProfile.caPrefix;
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700150 interestName.append("CA").append("NEW");
Davide Pesavento64d5c8f2022-03-07 22:06:22 -0500151 auto interest = std::make_shared<Interest>(interestName);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700152 interest->setMustBeFresh(true);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700153 interest->setApplicationParameters(
Davide Pesavento64d5c8f2022-03-07 22:06:22 -0500154 requesttlv::encodeApplicationParameters(RequestType::NEW, m_ecdh.getSelfPubKey(), certRequest));
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700155
156 // sign the Interest packet
tylerliu4140fe82021-01-27 15:45:44 -0800157 m_keyChain.sign(*interest, signingByKey(keyName));
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700158 return interest;
159}
160
Davide Pesavento0dc02012021-11-23 22:55:03 -0500161std::shared_ptr<Interest>
162Request::genRevokeInterest(const Certificate& certificate)
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700163{
Zhiyi Zhang6499edd2021-02-17 22:37:21 -0800164 if (!m_caProfile.caPrefix.isPrefixOf(certificate.getName())) {
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700165 return nullptr;
166 }
Davide Pesavento64d5c8f2022-03-07 22:06:22 -0500167
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700168 // generate Interest packet
Zhiyi Zhang6499edd2021-02-17 22:37:21 -0800169 Name interestName = m_caProfile.caPrefix;
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700170 interestName.append("CA").append("REVOKE");
Davide Pesavento64d5c8f2022-03-07 22:06:22 -0500171 auto interest = std::make_shared<Interest>(interestName);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700172 interest->setMustBeFresh(true);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700173 interest->setApplicationParameters(
Davide Pesavento64d5c8f2022-03-07 22:06:22 -0500174 requesttlv::encodeApplicationParameters(RequestType::REVOKE, m_ecdh.getSelfPubKey(), certificate));
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700175 return interest;
176}
177
178std::list<std::string>
tylerliu4140fe82021-01-27 15:45:44 -0800179Request::onNewRenewRevokeResponse(const Data& reply)
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700180{
Davide Pesavento0dc02012021-11-23 22:55:03 -0500181 if (!ndn::security::verifySignature(reply, *m_caProfile.cert)) {
Zhiyi Zhangd61b4a82020-10-10 15:18:43 -0700182 NDN_LOG_ERROR("Cannot verify replied Data packet signature.");
tylerliu41c11532020-10-10 16:14:45 -0700183 NDN_THROW(std::runtime_error("Cannot verify replied Data packet signature."));
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700184 }
185 processIfError(reply);
186
tylerliu4140fe82021-01-27 15:45:44 -0800187 const auto& contentTLV = reply.getContent();
Zhiyi Zhangbed854c2020-10-20 18:25:35 -0700188 std::vector<uint8_t> ecdhKey;
189 std::array<uint8_t, 32> salt;
Zhiyi Zhang6499edd2021-02-17 22:37:21 -0800190 auto challenges = requesttlv::decodeDataContent(contentTLV, ecdhKey, salt, m_requestId);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700191
Zhiyi Zhang91f86ab2020-10-05 15:36:35 -0700192 // ECDH and HKDF
Zhiyi Zhang6499edd2021-02-17 22:37:21 -0800193 auto sharedSecret = m_ecdh.deriveSecret(ecdhKey);
Zhiyi Zhangbed854c2020-10-20 18:25:35 -0700194 hkdf(sharedSecret.data(), sharedSecret.size(),
Zhiyi Zhang6499edd2021-02-17 22:37:21 -0800195 salt.data(), salt.size(), m_aesKey.data(), m_aesKey.size(),
196 m_requestId.data(), m_requestId.size());
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700197
198 // update state
Zhiyi Zhangbed854c2020-10-20 18:25:35 -0700199 return challenges;
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700200}
201
tylerliu40226332020-11-11 15:37:16 -0800202std::multimap<std::string, std::string>
tylerliu4140fe82021-01-27 15:45:44 -0800203Request::selectOrContinueChallenge(const std::string& challengeSelected)
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700204{
205 auto challenge = ChallengeModule::createChallengeModule(challengeSelected);
206 if (challenge == nullptr) {
tylerliu41c11532020-10-10 16:14:45 -0700207 NDN_THROW(std::runtime_error("The challenge selected is not supported by your current version of NDNCERT."));
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700208 }
Zhiyi Zhang6499edd2021-02-17 22:37:21 -0800209 m_challengeType = challengeSelected;
210 return challenge->getRequestedParameterList(m_status, m_challengeStatus);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700211}
212
Davide Pesavento0dc02012021-11-23 22:55:03 -0500213std::shared_ptr<Interest>
tylerliu4140fe82021-01-27 15:45:44 -0800214Request::genChallengeInterest(std::multimap<std::string, std::string>&& parameters)
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700215{
Davide Pesavento6f1a2ab2022-03-17 03:57:21 -0400216 if (m_challengeType.empty()) {
tylerliu41c11532020-10-10 16:14:45 -0700217 NDN_THROW(std::runtime_error("The challenge has not been selected."));
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700218 }
Zhiyi Zhang6499edd2021-02-17 22:37:21 -0800219 auto challenge = ChallengeModule::createChallengeModule(m_challengeType);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700220 if (challenge == nullptr) {
tylerliu41c11532020-10-10 16:14:45 -0700221 NDN_THROW(std::runtime_error("The challenge selected is not supported by your current version of NDNCERT."));
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700222 }
Davide Pesavento0d1d11c2022-04-11 22:11:34 -0400223 auto challengeParams = challenge->genChallengeRequestTLV(m_status, m_challengeStatus, parameters);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700224
Zhiyi Zhang6499edd2021-02-17 22:37:21 -0800225 Name interestName = m_caProfile.caPrefix;
Davide Pesavento6f1a2ab2022-03-17 03:57:21 -0400226 interestName.append("CA").append("CHALLENGE").append(Name::Component(m_requestId));
Davide Pesavento64d5c8f2022-03-07 22:06:22 -0500227 auto interest = std::make_shared<Interest>(interestName);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700228 interest->setMustBeFresh(true);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700229
230 // encrypt the Interest parameters
Zhiyi Zhang6499edd2021-02-17 22:37:21 -0800231 auto paramBlock = encodeBlockWithAesGcm128(ndn::tlv::ApplicationParameters, m_aesKey.data(),
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700232 challengeParams.value(), challengeParams.value_size(),
Zhiyi Zhang6499edd2021-02-17 22:37:21 -0800233 m_requestId.data(), m_requestId.size(),
234 m_encryptionIv);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700235 interest->setApplicationParameters(paramBlock);
tylerliu4140fe82021-01-27 15:45:44 -0800236 m_keyChain.sign(*interest, signingByKey(m_keyPair.getName()));
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700237 return interest;
238}
239
240void
tylerliu4140fe82021-01-27 15:45:44 -0800241Request::onChallengeResponse(const Data& reply)
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700242{
Davide Pesavento0dc02012021-11-23 22:55:03 -0500243 if (!ndn::security::verifySignature(reply, *m_caProfile.cert)) {
Zhiyi Zhangd61b4a82020-10-10 15:18:43 -0700244 NDN_LOG_ERROR("Cannot verify replied Data packet signature.");
tylerliu41c11532020-10-10 16:14:45 -0700245 NDN_THROW(std::runtime_error("Cannot verify replied Data packet signature."));
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700246 }
247 processIfError(reply);
tylerliu4140fe82021-01-27 15:45:44 -0800248 challengetlv::decodeDataContent(reply.getContent(), *this);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700249}
250
Davide Pesavento0dc02012021-11-23 22:55:03 -0500251std::shared_ptr<Interest>
tylerliu4140fe82021-01-27 15:45:44 -0800252Request::genCertFetchInterest() const
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700253{
Davide Pesavento64d5c8f2022-03-07 22:06:22 -0500254 auto interest = std::make_shared<Interest>(m_issuedCertName);
Tianyuan Yu60775552022-03-07 17:10:10 -0800255 if (!m_forwardingHint.empty()) {
256 interest->setForwardingHint({m_forwardingHint});
257 }
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700258 return interest;
259}
260
Davide Pesavento0dc02012021-11-23 22:55:03 -0500261std::shared_ptr<Certificate>
tylerliu4140fe82021-01-27 15:45:44 -0800262Request::onCertFetchResponse(const Data& reply)
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700263{
264 try {
Davide Pesavento0dc02012021-11-23 22:55:03 -0500265 return std::make_shared<Certificate>(reply);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700266 }
Davide Pesavento0dc02012021-11-23 22:55:03 -0500267 catch (const std::exception&) {
Davide Pesavento64d5c8f2022-03-07 22:06:22 -0500268 NDN_LOG_ERROR("Cannot parse replied certificate");
269 NDN_THROW(std::runtime_error("Cannot parse replied certificate"));
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700270 }
271}
272
273void
tylerliu4140fe82021-01-27 15:45:44 -0800274Request::processIfError(const Data& data)
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700275{
Zhiyi Zhangf22ae242020-11-17 10:51:15 -0800276 auto errorInfo = errortlv::decodefromDataContent(data.getContent());
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700277 if (std::get<0>(errorInfo) == ErrorCode::NO_ERROR) {
278 return;
279 }
Zhiyi Zhang1a222692020-10-16 11:35:49 -0700280 NDN_LOG_ERROR("Error info replied from the CA with Error code: " << std::get<0>(errorInfo) <<
281 " and Error Info: " << std::get<1>(errorInfo));
tylerliu41c11532020-10-10 16:14:45 -0700282 NDN_THROW(std::runtime_error("Error info replied from the CA with Error code: " +
Zhiyi Zhang1a222692020-10-16 11:35:49 -0700283 boost::lexical_cast<std::string>(std::get<0>(errorInfo)) +
284 " and Error Info: " + std::get<1>(errorInfo)));
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700285}
286
Davide Pesavento0d1d11c2022-04-11 22:11:34 -0400287} // namespace ndncert::requester