blob: c17ce823d228b65ce1c7830541ade296de59519c [file] [log] [blame]
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2017 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_SECURITY_V2_VALIDATOR_HPP
#define NDN_SECURITY_V2_VALIDATOR_HPP
#include "certificate.hpp"
#include "certificate-cache.hpp"
#include "certificate-request.hpp"
#include "trust-anchor-container.hpp"
#include "validation-callback.hpp"
#include "validation-policy.hpp"
#include "validation-state.hpp"
namespace ndn {
class Face;
namespace lp {
class Nack;
} // namespace lp
namespace security {
namespace v2 {
/**
* @brief Interface for validating data and interest packets.
*
* Every time a validation process initiated, it creates a ValidationState that exist until
* validation finishes with either success or failure. This state serves several purposes:
* - record Interest or Data packet being validated
* - record failure callback
* - record certificates in the certification chain for the Interest or Data packet being validated
* - record names of the requested certificates to detect loops in the certificate chain
* - keep track of the validation chain size (aka validation "depth")
*
* During validation, policy can augment validation state with policy- and fetcher-specific
* information using ndn::Tag's.
*
* A validator has a trust anchor cache to save static and dynamic trust anchors, a verified
* certificate cache for saving certificates that are already verified and an unverified
* certificate cache for saving prefetched but not yet verified certificates.
*
* @todo Limit the maximum time the validation process is allowed to run before declaring failure
* @todo Ability to customize maximum lifetime for trusted and untrusted certificate caches.
* Current implementation hard-codes them to be 1 hour and 5 minutes.
*/
class Validator : noncopyable
{
public:
/**
* @brief Validator constructor.
*
* @param policy Validation policy to be associated with the validator
* @param face Face for fetching certificates from network. If provided, the Validator
* operates in online mode; otherwise, the Validator operates in offline mode.
*/
explicit
Validator(unique_ptr<ValidationPolicy> policy, Face* face = nullptr);
~Validator();
/**
* @brief Set the maximum depth of the certificate chain
*/
void
setMaxDepth(size_t depth);
/**
* @return The maximum depth of the certificate chain
*/
size_t
getMaxDepth() const;
/**
* @brief Asynchronously validate @p data
*
* @note @p successCb and @p failureCb must not be nullptr
*/
void
validate(const Data& data,
const DataValidationSuccessCallback& successCb,
const DataValidationFailureCallback& failureCb);
/**
* @brief Asynchronously validate @p interest
*
* @note @p successCb and @p failureCb must not be nullptr
*/
void
validate(const Interest& interest,
const InterestValidationSuccessCallback& successCb,
const InterestValidationFailureCallback& failureCb);
public: // anchor management
/**
* @brief load static trust anchor.
*
* Static trust anchors are permanently associated with the validator and never expire.
*
* @param groupId Certificate group id.
* @param cert Certificate to load as a trust anchor.
*/
void
loadAnchor(const std::string& groupId, Certificate&& cert);
/**
* @brief load dynamic trust anchors.
*
* Dynamic trust anchors are associated with the validator for as long as the underlying
* trust anchor file (set of files) exist(s).
*
* @param groupId Certificate group id, must not be empty.
* @param certfilePath Specifies the path to load the trust anchors.
* @param refreshPeriod Refresh period for the trust anchors, must be positive.
* @param isDir Tells whether the path is a directory or a single file.
*/
void
loadAnchor(const std::string& groupId, const std::string& certfilePath,
time::nanoseconds refreshPeriod, bool isDir = false);
/**
* @brief Cache verified @p cert a period of time (1 hour)
*
* @todo Add ability to customize time period
*/
void
cacheVerifiedCertificate(Certificate&& cert);
/**
* @brief Cache unverified @p cert for a period of time (5 minutes)
*
* @todo Add ability to customize time period
*/
void
cacheUnverifiedCertificate(Certificate&& cert);
/**
* @return Trust anchor container
*/
const TrustAnchorContainer&
getTrustAnchors() const;
/**
* @return Verified certificate cache
*/
const CertificateCache&
getVerifiedCertificateCache() const;
/**
* @return Unverified certificate cache
*/
const CertificateCache&
getUnverifiedCertificateCache() const;
/**
* @brief Check if certificate with @p certName exists in verified or unverified cache
*/
bool
isCertificateCached(const Name& certName) const;
private: // Common validator operations
/**
* @brief Recursive validation of the certificate in the certification chain
*
* @param cert The certificate to check.
* @param state The current validation state.
*/
void
validate(const Certificate& cert, const shared_ptr<ValidationState>& state);
/**
* @brief Request certificate for further validation.
*
* @param certRequest Certificate request.
* @param state The current validation state.
*/
void
requestCertificate(const shared_ptr<CertificateRequest>& certRequest,
const shared_ptr<ValidationState>& state);
/**
* @brief Find trusted certificate among trust anchors and verified certificates.
*
* @param interestForCertificate Interest for certificate
* @param state The current validation state.
*
* @return found certificate, nullptr if not found.
*
* @note The returned pointer may get invalidated after next findTrustedCert call.
*/
const Certificate*
findTrustedCert(const Interest& interestForCertificate,
const shared_ptr<ValidationState>& state);
/**
* @brief fetch certificate from network based on certificate request.
*
* @param certRequest Certificate request.
* @param state The current validation state.
*/
void
fetchCertificateFromNetwork(const shared_ptr<CertificateRequest>& certRequest,
const shared_ptr<ValidationState>& state);
/**
* @brief Callback invoked when certificated is retrieved.
*
* @param data Retrieved certificate.
* @param certRequest Certificate request.
* @param state The current validation state.
* @param isFromNetwork Flag to indicate that the data packet is retrieved (to avoid re-caching).
*/
void
dataCallback(const Data& data,
const shared_ptr<CertificateRequest>& certRequest,
const shared_ptr<ValidationState>& state,
bool isFromNetwork = true);
/**
* @brief Callback invoked when interest for fetching certificate gets NACKed.
*
* It will retry for pre-configured amount of retries.
*
* @param nack Received NACK
* @param certRequest Certificate request.
* @param state The current validation state.
*/
void
nackCallback(const lp::Nack& nack, const shared_ptr<CertificateRequest>& certRequest,
const shared_ptr<ValidationState>& state);
/**
* @brief Callback invoked when interest for fetching certificate times out.
*
* It will retry for pre-configured amount of retries.
*
* @param certRequest Certificate request.
* @param state The current validation state.
*/
void
timeoutCallback(const shared_ptr<CertificateRequest>& certRequest,
const shared_ptr<ValidationState>& state);
private:
unique_ptr<ValidationPolicy> m_policy;
Face* m_face;
TrustAnchorContainer m_trustAnchors;
CertificateCache m_verifiedCertificateCache;
CertificateCache m_unverifiedCertificateCache;
size_t m_maxDepth;
};
} // namespace v2
} // namespace security
} // namespace ndn
#endif // NDN_SECURITY_V2_VALIDATOR_HPP