v2/validator.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
22 #include "validator.hpp"
23 
24 #include "face.hpp"
26 #include "util/logger.hpp"
27 
28 namespace ndn {
29 namespace security {
30 namespace v2 {
31 
33 
34 #define NDN_LOG_DEBUG_DEPTH(x) NDN_LOG_DEBUG(std::string(state->getDepth() + 1, '>') << " " << x)
35 #define NDN_LOG_TRACE_DEPTH(x) NDN_LOG_TRACE(std::string(state->getDepth() + 1, '>') << " " << x)
36 
37 Validator::Validator(unique_ptr<ValidationPolicy> policy, unique_ptr<CertificateFetcher> certFetcher)
38  : m_policy(std::move(policy))
39  , m_certFetcher(std::move(certFetcher))
40  , m_maxDepth(25)
41 {
42  BOOST_ASSERT(m_policy != nullptr);
43  BOOST_ASSERT(m_certFetcher != nullptr);
44  m_certFetcher->setCertificateStorage(*this);
45 }
46 
47 Validator::~Validator() = default;
48 
49 void
51 {
52  m_maxDepth = depth;
53 }
54 
55 size_t
57 {
58  return m_maxDepth;
59 }
60 
61 void
63  const DataValidationSuccessCallback& successCb,
64  const DataValidationFailureCallback& failureCb)
65 {
66  auto state = make_shared<DataValidationState>(data, successCb, failureCb);
67  NDN_LOG_DEBUG_DEPTH("Start validating data " << data.getName());
68 
69  m_policy->checkPolicy(data, state,
70  [this] (const shared_ptr<CertificateRequest>& certRequest, const shared_ptr<ValidationState>& state) {
71  if (certRequest == nullptr) {
72  state->bypassValidation();
73  }
74  else {
75  // need to fetch key and validate it
76  requestCertificate(certRequest, state);
77  }
78  });
79 }
80 
81 void
82 Validator::validate(const Interest& interest,
83  const InterestValidationSuccessCallback& successCb,
84  const InterestValidationFailureCallback& failureCb)
85 {
86  auto state = make_shared<InterestValidationState>(interest, successCb, failureCb);
87  NDN_LOG_DEBUG_DEPTH("Start validating interest " << interest.getName());
88 
89  m_policy->checkPolicy(interest, state,
90  [this] (const shared_ptr<CertificateRequest>& certRequest, const shared_ptr<ValidationState>& state) {
91  if (certRequest == nullptr) {
92  state->bypassValidation();
93  }
94  else {
95  // need to fetch key and validate it
96  requestCertificate(certRequest, state);
97  }
98  });
99 }
100 
101 void
102 Validator::validate(const Certificate& cert, const shared_ptr<ValidationState>& state)
103 {
104  NDN_LOG_DEBUG_DEPTH("Start validating certificate " << cert.getName());
105 
106  if (!cert.isValid()) {
107  return state->fail({ValidationError::Code::EXPIRED_CERT, "Retrieved certificate is not yet valid or expired "
108  "`" + cert.getName().toUri() + "`"});
109  }
110 
111  m_policy->checkPolicy(cert, state,
112  [this, cert] (const shared_ptr<CertificateRequest>& certRequest, const shared_ptr<ValidationState>& state) {
113  if (certRequest == nullptr) {
114  state->fail({ValidationError::POLICY_ERROR, "Validation policy is not allowed to designate `" +
115  cert.getName().toUri() + "` as a trust anchor"});
116  }
117  else {
118  // need to fetch key and validate it
119  state->addCertificate(cert);
120  requestCertificate(certRequest, state);
121  }
122  });
123 }
124 
125 void
126 Validator::requestCertificate(const shared_ptr<CertificateRequest>& certRequest,
127  const shared_ptr<ValidationState>& state)
128 {
129  // TODO configurable check for the maximum number of steps
130  if (state->getDepth() >= m_maxDepth) {
131  state->fail({ValidationError::Code::EXCEEDED_DEPTH_LIMIT,
132  "Exceeded validation depth limit (" + to_string(m_maxDepth) + ")"});
133  return;
134  }
135 
136  NDN_LOG_DEBUG_DEPTH("Retrieving " << certRequest->m_interest.getName());
137 
138  auto cert = findTrustedCert(certRequest->m_interest);
139  if (cert != nullptr) {
140  NDN_LOG_TRACE_DEPTH("Found trusted certificate " << cert->getName());
141 
142  cert = state->verifyCertificateChain(*cert);
143  if (cert != nullptr) {
144  state->verifyOriginalPacket(*cert);
145  }
146  for (auto trustedCert = std::make_move_iterator(state->m_certificateChain.begin());
147  trustedCert != std::make_move_iterator(state->m_certificateChain.end());
148  ++trustedCert) {
149  cacheVerifiedCertificate(*trustedCert);
150  }
151  return;
152  }
153 
154  m_certFetcher->fetch(certRequest, state, [this] (const Certificate& cert, const shared_ptr<ValidationState>& state) {
155  validate(cert, state);
156  });
157 }
158 
160 // Trust anchor management
162 
163 // to change visibility from protected to public
164 
165 void
166 Validator::loadAnchor(const std::string& groupId, Certificate&& cert)
167 {
168  CertificateStorage::loadAnchor(groupId, std::move(cert));
169 }
170 
171 void
172 Validator::loadAnchor(const std::string& groupId, const std::string& certfilePath,
173  time::nanoseconds refreshPeriod, bool isDir)
174 {
175  CertificateStorage::loadAnchor(groupId, certfilePath, refreshPeriod, isDir);
176 }
177 
178 void
180 {
181  CertificateStorage::cacheVerifiedCert(std::move(cert));
182 }
183 
184 } // namespace v2
185 } // namespace security
186 } // namespace ndn
bool isValid(const time::system_clock::TimePoint &ts=time::system_clock::now()) const
Check if the certificate is valid at ts.
void loadAnchor(const std::string &groupId, Certificate &&cert)
load static trust anchor.
Copyright (c) 2013-2016 Regents of the University of California.
Definition: common.hpp:74
The certificate following the certificate format naming convention.
function< void(const Data &data)> DataValidationSuccessCallback
Callback to report a successful Data validation.
void cacheVerifiedCertificate(Certificate &&cert)
Cache verified cert a period of time (1 hour)
STL namespace.
#define NDN_LOG_DEBUG_DEPTH(x)
represents an Interest packet
Definition: interest.hpp:42
function< void(const Data &data, const ValidationError &error)> DataValidationFailureCallback
Callback to report a failed Data validation.
#define NDN_LOG_TRACE_DEPTH(x)
#define NDN_LOG_INIT(name)
declare a log module
Definition: logger.hpp:97
void setMaxDepth(size_t depth)
Set the maximum depth of the certificate chain.
const Name & getName() const
Get name of the Data packet.
Definition: data.hpp:318
std::string toUri() const
Encode this name as a URI.
Definition: name.cpp:171
void cacheVerifiedCert(Certificate &&cert)
Cache verified certificate a period of time (1 hour)
void validate(const Data &data, const DataValidationSuccessCallback &successCb, const DataValidationFailureCallback &failureCb)
Asynchronously validate data.
void loadAnchor(const std::string &groupId, Certificate &&cert)
load static trust anchor.
const Certificate * findTrustedCert(const Interest &interestForCert) const
Find a trusted certificate in trust anchor container or in verified cache.
Validator(unique_ptr< ValidationPolicy > policy, unique_ptr< CertificateFetcher > certFetcher)
Validator constructor.
function< void(const Interest &interest, const ValidationError &error)> InterestValidationFailureCallback
Callback to report a failed Interest validation.
std::string to_string(const V &v)
Definition: backports.hpp:51
represents a Data packet
Definition: data.hpp:37
function< void(const Interest &interest)> InterestValidationSuccessCallback
Callback to report a successful Interest validation.
Interface for validating data and interest packets.