258 lines
6.8 KiB
C++
258 lines
6.8 KiB
C++
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
|
/*
|
|
* Copyright (c) 2013-2023 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_CXX_TESTS_UNIT_SECURITY_VALIDATOR_FIXTURE_HPP
|
|
#define NDN_CXX_TESTS_UNIT_SECURITY_VALIDATOR_FIXTURE_HPP
|
|
|
|
#include "ndn-cxx/security/validator.hpp"
|
|
#include "ndn-cxx/security/certificate-fetcher-from-network.hpp"
|
|
#include "ndn-cxx/util/dummy-client-face.hpp"
|
|
|
|
#include "tests/boost-test.hpp"
|
|
#include "tests/unit/io-key-chain-fixture.hpp"
|
|
|
|
#include <boost/lexical_cast.hpp>
|
|
|
|
namespace ndn {
|
|
namespace security {
|
|
inline namespace v2 {
|
|
namespace tests {
|
|
|
|
class ValidatorFixtureBase : public ndn::tests::IoKeyChainFixture
|
|
{
|
|
protected:
|
|
ValidatorFixtureBase();
|
|
|
|
void
|
|
mockNetworkOperations();
|
|
|
|
/**
|
|
* @brief Undo clock advancement of mockNetworkOperations()
|
|
*/
|
|
void
|
|
rewindClockAfterValidation();
|
|
|
|
/**
|
|
* @brief Issues a certificate for @p subIdentityName signed by @p issuer
|
|
*
|
|
* If the identity does not exist, it is created.
|
|
* A new key is generated as the default key for the identity.
|
|
* A default certificate for the key is signed by the issuer using its default certificate.
|
|
*
|
|
* @return The sub-identity
|
|
*/
|
|
Identity
|
|
addSubCertificate(const Name& subIdentityName, const Identity& issuer);
|
|
|
|
protected:
|
|
util::DummyClientFace face{m_io, {true, true}};
|
|
std::function<void(const Interest&)> processInterest;
|
|
CertificateCache cache{100_days};
|
|
ValidationError lastError{ValidationError::NO_ERROR};
|
|
|
|
private:
|
|
static const time::milliseconds s_mockPeriod;
|
|
static const int s_mockTimes;
|
|
};
|
|
|
|
template<class ValidationPolicyT, class CertificateFetcherT = CertificateFetcherFromNetwork>
|
|
class ValidatorFixture : public ValidatorFixtureBase
|
|
{
|
|
protected:
|
|
ValidatorFixture()
|
|
: validator(make_unique<ValidationPolicyT>(), make_unique<CertificateFetcherT>(face))
|
|
, policy(static_cast<ValidationPolicyT&>(validator.getPolicy()))
|
|
{
|
|
}
|
|
|
|
template<class Packet>
|
|
void
|
|
validate(const Packet& packet, const std::string& msg, bool expectSuccess, int line)
|
|
{
|
|
std::string detailedInfo = msg + " on line " + to_string(line);
|
|
size_t nCallbacks = 0;
|
|
this->validator.validate(packet,
|
|
[&] (const Packet&) {
|
|
lastError = ValidationError::NO_ERROR;
|
|
++nCallbacks;
|
|
BOOST_CHECK_MESSAGE(expectSuccess,
|
|
(expectSuccess ? "OK: " : "FAILED: ") + detailedInfo);
|
|
},
|
|
[&] (const Packet&, const ValidationError& error) {
|
|
lastError = error;
|
|
++nCallbacks;
|
|
BOOST_CHECK_MESSAGE(!expectSuccess,
|
|
(!expectSuccess ? "OK: " : "FAILED: ") + detailedInfo +
|
|
(expectSuccess ? " (" + boost::lexical_cast<std::string>(error) + ")" : ""));
|
|
});
|
|
|
|
mockNetworkOperations();
|
|
BOOST_CHECK_EQUAL(nCallbacks, 1);
|
|
}
|
|
|
|
protected:
|
|
Validator validator;
|
|
ValidationPolicyT& policy;
|
|
};
|
|
|
|
template<class ValidationPolicyT, class CertificateFetcherT = CertificateFetcherFromNetwork>
|
|
class HierarchicalValidatorFixture : public ValidatorFixture<ValidationPolicyT, CertificateFetcherT>
|
|
{
|
|
protected:
|
|
HierarchicalValidatorFixture()
|
|
{
|
|
identity = this->m_keyChain.createIdentity("/Security/ValidatorFixture");
|
|
subIdentity = this->addSubCertificate("/Security/ValidatorFixture/Sub1", identity);
|
|
subSelfSignedIdentity = this->m_keyChain.createIdentity("/Security/ValidatorFixture/Sub1/Sub2");
|
|
otherIdentity = this->m_keyChain.createIdentity("/Security/OtherIdentity");
|
|
|
|
this->validator.loadAnchor("", Certificate(identity.getDefaultKey().getDefaultCertificate()));
|
|
|
|
this->cache.insert(identity.getDefaultKey().getDefaultCertificate());
|
|
this->cache.insert(subIdentity.getDefaultKey().getDefaultCertificate());
|
|
this->cache.insert(subSelfSignedIdentity.getDefaultKey().getDefaultCertificate());
|
|
this->cache.insert(otherIdentity.getDefaultKey().getDefaultCertificate());
|
|
}
|
|
|
|
protected:
|
|
Identity identity;
|
|
Identity subIdentity;
|
|
Identity subSelfSignedIdentity;
|
|
Identity otherIdentity;
|
|
};
|
|
|
|
#define VALIDATE_SUCCESS(packet, message) this->validate(packet, message, true, __LINE__)
|
|
#define VALIDATE_FAILURE(packet, message) this->validate(packet, message, false, __LINE__)
|
|
|
|
class DummyValidationState : public ValidationState
|
|
{
|
|
public:
|
|
~DummyValidationState() override
|
|
{
|
|
m_outcome = false;
|
|
}
|
|
|
|
void
|
|
fail(const ValidationError&) override
|
|
{
|
|
m_outcome = false;
|
|
}
|
|
|
|
private:
|
|
void
|
|
verifyOriginalPacket(const std::optional<Certificate>&) override
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
void
|
|
bypassValidation() override
|
|
{
|
|
// do nothing
|
|
}
|
|
};
|
|
|
|
struct DataPkt
|
|
{
|
|
static constexpr uint32_t
|
|
getType()
|
|
{
|
|
return tlv::Data;
|
|
}
|
|
|
|
static Name
|
|
makeName(Name name, KeyChain&)
|
|
{
|
|
return name;
|
|
}
|
|
|
|
static Data
|
|
makePacket(const Name& name)
|
|
{
|
|
return Data(name);
|
|
}
|
|
|
|
static shared_ptr<ValidationState>
|
|
makeState()
|
|
{
|
|
return make_shared<DummyValidationState>();
|
|
}
|
|
};
|
|
|
|
struct InterestV02Pkt
|
|
{
|
|
static constexpr uint32_t
|
|
getType()
|
|
{
|
|
return tlv::Interest;
|
|
}
|
|
|
|
static Name
|
|
makeName(Name name, KeyChain& keyChain);
|
|
|
|
static Interest
|
|
makePacket(const Name& name)
|
|
{
|
|
return Interest(name);
|
|
}
|
|
|
|
static shared_ptr<ValidationState>
|
|
makeState()
|
|
{
|
|
auto state = make_shared<DummyValidationState>();
|
|
state->setTag(make_shared<SignedInterestFormatTag>(SignedInterestFormat::V02));
|
|
return state;
|
|
}
|
|
};
|
|
|
|
struct InterestV03Pkt
|
|
{
|
|
static constexpr uint32_t
|
|
getType()
|
|
{
|
|
return tlv::Interest;
|
|
}
|
|
|
|
static Name
|
|
makeName(Name name, KeyChain& keyChain);
|
|
|
|
static Interest
|
|
makePacket(const Name& name)
|
|
{
|
|
return Interest(name);
|
|
}
|
|
|
|
static shared_ptr<ValidationState>
|
|
makeState()
|
|
{
|
|
auto state = make_shared<DummyValidationState>();
|
|
state->setTag(make_shared<SignedInterestFormatTag>(SignedInterestFormat::V03));
|
|
return state;
|
|
}
|
|
};
|
|
|
|
} // namespace tests
|
|
} // inline namespace v2
|
|
} // namespace security
|
|
} // namespace ndn
|
|
|
|
#endif // NDN_CXX_TESTS_UNIT_SECURITY_VALIDATOR_FIXTURE_HPP
|