ndn-cxx: NDN C++ Library 0.9.0-33-g832ea91d
Loading...
Searching...
No Matches
validator.cpp
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2013-2023 Regents of the University of California.
4 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library 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 Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
24
25#include <boost/lexical_cast.hpp>
26
27namespace ndn::security {
28
30
31#define NDN_LOG_DEBUG_DEPTH(x) NDN_LOG_DEBUG(std::string(state->getDepth() + 1, '>') << " " << x)
32#define NDN_LOG_TRACE_DEPTH(x) NDN_LOG_TRACE(std::string(state->getDepth() + 1, '>') << " " << x)
33
34Validator::Validator(unique_ptr<ValidationPolicy> policy, unique_ptr<CertificateFetcher> certFetcher)
35 : m_policy(std::move(policy))
36 , m_certFetcher(std::move(certFetcher))
37{
38 BOOST_ASSERT(m_policy != nullptr);
39 BOOST_ASSERT(m_certFetcher != nullptr);
40 m_policy->setValidator(*this);
41 m_certFetcher->setCertificateStorage(*this);
42}
43
44Validator::~Validator() noexcept = default;
45
46void
47Validator::validate(const Data& data,
48 const DataValidationSuccessCallback& successCb,
49 const DataValidationFailureCallback& failureCb)
50{
51 auto state = make_shared<DataValidationState>(data, successCb, failureCb);
52 NDN_LOG_DEBUG_DEPTH("Start validating data " << data.getName());
53
54 m_policy->checkPolicy(data, state, [this] (auto&&... args) {
55 continueValidation(std::forward<decltype(args)>(args)...);
56 });
57}
58
59void
61 const InterestValidationSuccessCallback& successCb,
62 const InterestValidationFailureCallback& failureCb)
63{
64 auto state = make_shared<InterestValidationState>(interest, successCb, failureCb);
65 NDN_LOG_DEBUG_DEPTH("Start validating interest " << interest.getName());
66
67 try {
69 state->setTag(make_shared<SignedInterestFormatTag>(fmt));
70 }
71 catch (const tlv::Error& e) {
72 return state->fail({ValidationError::MALFORMED_SIGNATURE, "Malformed InterestSignatureInfo in `" +
73 interest.getName().toUri() + "`: " + e.what()});
74 }
75
76 m_policy->checkPolicy(interest, state, [this] (auto&&... args) {
77 continueValidation(std::forward<decltype(args)>(args)...);
78 });
79}
80
81void
82Validator::validate(const Certificate& cert, const shared_ptr<ValidationState>& state)
83{
84 NDN_LOG_DEBUG_DEPTH("Start validating certificate " << cert.getName());
85
86 if (!cert.isValid()) {
87 return state->fail({ValidationError::EXPIRED_CERT, "`" + cert.getName().toUri() + "` is valid "
88 "between " + boost::lexical_cast<std::string>(cert.getValidityPeriod())});
89 }
90
91 m_policy->checkPolicy(cert, state,
92 [this, cert] (const shared_ptr<CertificateRequest>& certRequest, const shared_ptr<ValidationState>& state) {
93 if (certRequest == nullptr) {
94 state->fail({ValidationError::POLICY_ERROR, "Validation policy is not allowed to designate `" +
95 cert.getName().toUri() + "` as a trust anchor"});
96 }
97 else {
98 // need to fetch key and validate it
99 state->addCertificate(cert);
100 requestCertificate(certRequest, state);
101 }
102 });
103}
104
105void
106Validator::continueValidation(const shared_ptr<CertificateRequest>& certRequest,
107 const shared_ptr<ValidationState>& state)
108{
109 BOOST_ASSERT(state);
110
111 if (certRequest == nullptr) {
112 state->bypassValidation();
113 }
114 else {
115 // need to fetch key and validate it
116 requestCertificate(certRequest, state);
117 }
118}
119
120void
121Validator::requestCertificate(const shared_ptr<CertificateRequest>& certRequest,
122 const shared_ptr<ValidationState>& state)
123{
124 if (state->getDepth() >= m_maxDepth) {
125 state->fail({ValidationError::EXCEEDED_DEPTH_LIMIT, to_string(m_maxDepth)});
126 return;
127 }
128
129 if (certRequest->interest.getName() == SigningInfo::getDigestSha256Identity()) {
130 state->verifyOriginalPacket(std::nullopt);
131 return;
132 }
133
134 if (state->hasSeenCertificateName(certRequest->interest.getName())) {
135 state->fail({ValidationError::LOOP_DETECTED, certRequest->interest.getName().toUri()});
136 return;
137 }
138
139 NDN_LOG_DEBUG_DEPTH("Retrieving " << certRequest->interest.getName());
140
141 auto cert = findTrustedCert(certRequest->interest);
142 if (cert != nullptr) {
143 NDN_LOG_TRACE_DEPTH("Found trusted certificate " << cert->getName());
144
145 cert = state->verifyCertificateChain(*cert);
146 if (cert != nullptr) {
147 state->verifyOriginalPacket(*cert);
148 }
149 for (auto trustedCert = std::make_move_iterator(state->m_certificateChain.begin());
150 trustedCert != std::make_move_iterator(state->m_certificateChain.end());
151 ++trustedCert) {
152 cacheVerifiedCertificate(*trustedCert);
153 }
154 return;
155 }
156
157 m_certFetcher->fetch(certRequest, state, [this] (auto&&... args) {
158 validate(std::forward<decltype(args)>(args)...);
159 });
160}
161
163// Trust anchor management
165
166// to change visibility from protected to public
167
168void
169Validator::loadAnchor(const std::string& groupId, Certificate&& cert)
170{
171 CertificateStorage::loadAnchor(groupId, std::move(cert));
172}
173
174void
175Validator::loadAnchor(const std::string& groupId, const std::string& certfilePath,
176 time::nanoseconds refreshPeriod, bool isDir)
177{
178 CertificateStorage::loadAnchor(groupId, certfilePath, refreshPeriod, isDir);
179}
180
181void
186
187void
192
193void
198
199} // namespace ndn::security
#define NDN_LOG_DEBUG_DEPTH(x)
#define NDN_LOG_TRACE_DEPTH(x)
Represents a Data packet.
Definition data.hpp:39
Represents an Interest packet.
Definition interest.hpp:50
std::optional< SignatureInfo > getSignatureInfo() const
Get the InterestSignatureInfo element.
Definition interest.cpp:552
const Name & getName() const noexcept
Get the Interest name.
Definition interest.hpp:179
const Certificate * findTrustedCert(const Interest &interestForCert) const
Find a trusted certificate in trust anchor container or in verified cache.
void resetAnchors()
Remove any previously loaded static or dynamic trust anchor.
void cacheVerifiedCert(Certificate &&cert)
Cache verified certificate a period of time (1 hour).
void loadAnchor(const std::string &groupId, Certificate &&cert)
Load static trust anchor.
void resetVerifiedCerts()
Remove any cached verified certificates.
Represents an NDN certificate.
static const Name & getDigestSha256Identity()
A localhost identity to indicate that the signature is generated using SHA-256.
@ EXCEEDED_DEPTH_LIMIT
Exceeded validation depth limit.
@ EXPIRED_CERT
The certificate expired or is not yet valid.
@ POLICY_ERROR
The packet violates the validation rules enforced by the policy.
@ LOOP_DETECTED
Loop detected in the certification chain.
@ MALFORMED_SIGNATURE
The signature (e.g., SignatureInfo element) is missing or malformed.
Interface for validating data and interest packets.
Definition validator.hpp:61
void cacheVerifiedCertificate(Certificate &&cert)
Cache verified cert a period of time (1 hour).
void loadAnchor(const std::string &groupId, Certificate &&cert)
Load static trust anchor.
void validate(const Data &data, const DataValidationSuccessCallback &successCb, const DataValidationFailureCallback &failureCb)
Asynchronously validate data.
Definition validator.cpp:47
void resetVerifiedCertificates()
Remove any cached verified certificates.
void resetAnchors()
Remove any previously loaded static or dynamic trust anchor.
Validator(unique_ptr< ValidationPolicy > policy, unique_ptr< CertificateFetcher > certFetcher)
Validator constructor.
Definition validator.cpp:34
Represents an error in TLV encoding or decoding.
Definition tlv.hpp:54
#define NDN_LOG_INIT(name)
Define a non-member log module.
Definition logger.hpp:169
std::string to_string(const errinfo_stacktrace &x)
Definition exception.cpp:30
Contains the ndn-cxx security framework.
std::function< void(const Interest &)> InterestValidationSuccessCallback
Callback to report a successful Interest validation.
std::function< void(const Interest &, const ValidationError &)> InterestValidationFailureCallback
Callback to report a failed Interest validation.
std::function< void(const Data &)> DataValidationSuccessCallback
Callback to report a successful Data validation.
@ V03
Sign Interest using Packet Specification v0.3 semantics.
@ V02
Sign Interest using Packet Specification v0.2 semantics.
std::function< void(const Data &, const ValidationError &)> DataValidationFailureCallback
Callback to report a failed Data validation.
::boost::chrono::nanoseconds nanoseconds
Definition time.hpp:54
Definition data.cpp:25
STL namespace.