Browse Source

security: Enable validator fetch cert directly from interest sender

Change-Id: I8fab50145a9a053c85c1b2c6be752ba71b0120ef
Refs: #2237
pull/1/merge
Zhiyi Zhang 9 years ago
parent
commit
48becde5b4
  1. 2
      AUTHORS.md
  2. 15
      src/security/validation-request.hpp
  3. 14
      src/security/validator-config.cpp
  4. 5
      src/security/validator-config.hpp
  5. 21
      src/security/validator.cpp
  6. 27
      src/security/validator.hpp
  7. 153
      tests/unit-tests/security/validator-config.t.cpp

2
AUTHORS.md

@ -39,4 +39,4 @@ in the library:
* Marcin Juszkiewicz <http://marcin.juszkiewicz.com.pl/>
* Susmit Shannigrahi <https://www.linkedin.com/in/susmit-shannigrahi-90433b8>
* José Quevedo <http://atnog.av.it.pt/members/jquevedo>
* Zhiyi Zhang <zhangzhiyi1919@cs.ucla.edu>
* Zhiyi Zhang <http://irl.cs.ucla.edu/~zhiyi/>

15
src/security/validation-request.hpp

@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2016 Regents of the University of California.
* Copyright (c) 2013-2017 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@ -17,8 +17,6 @@
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*
* @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
*/
#ifndef NDN_SECURITY_VALIDATION_REQUEST_HPP
@ -58,17 +56,14 @@ public:
ValidationRequest(const Interest& interest,
const OnDataValidated& onDataValidated,
const OnDataValidationFailed& onDataValidationFailed,
int nRetries, int nSteps)
int nRetries, int nSteps,
uint64_t requesterFaceId = 0)
: m_interest(interest)
, m_onDataValidated(onDataValidated)
, m_onDataValidationFailed(onDataValidationFailed)
, m_nRetries(nRetries)
, m_nSteps(nSteps)
{
}
virtual
~ValidationRequest()
, m_requesterFaceId(requesterFaceId)
{
}
@ -82,6 +77,8 @@ public:
int m_nRetries;
/// @brief the number of validation steps that have been performed.
int m_nSteps;
/// @brief the incoming face id of the origin packet.
uint64_t m_requesterFaceId;
};
} // namespace security

14
src/security/validator-config.cpp

@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2016 Regents of the University of California.
* Copyright (c) 2013-2017 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@ -17,14 +17,12 @@
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*
* @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
* @author Zhiyi Zhang <zhangzhiyi1919@gmail.com>
*/
#include "validator-config.hpp"
#include "certificate-cache-ttl.hpp"
#include "../util/io.hpp"
#include "../lp/tags.hpp"
#include <boost/filesystem.hpp>
#include <boost/property_tree/info_parser.hpp>
@ -722,10 +720,16 @@ ValidatorConfig::checkSignature(const Packet& packet,
Interest certInterest(keyLocatorName);
uint64_t incomingFaceId = 0;
auto incomingFaceIdTag = packet.template getTag<lp::IncomingFaceIdTag>();
if (incomingFaceIdTag != nullptr) {
incomingFaceId = incomingFaceIdTag->get();
}
auto nextStep = make_shared<ValidationRequest>(certInterest,
onCertValidated,
onCertValidationFailed,
1, nSteps + 1);
1, nSteps + 1,
incomingFaceId);
nextSteps.push_back(nextStep);
return;

5
src/security/validator-config.hpp

@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2016 Regents of the University of California.
* Copyright (c) 2013-2017 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@ -17,9 +17,6 @@
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*
* @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
* @author Zhiyi Zhang <zhangzhiyi1919@gmail.com>
*/
#ifndef NDN_SECURITY_VALIDATOR_CONFIG_HPP

21
src/security/validator.cpp

@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2016 Regents of the University of California.
* Copyright (c) 2013-2017 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@ -17,13 +17,11 @@
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*
* @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
* @author Jeff Thompson <jefft0@remap.ucla.edu>
*/
#include "validator.hpp"
#include "../util/crypto.hpp"
#include "../lp/tags.hpp"
#include "v1/cryptopp.hpp"
@ -35,11 +33,12 @@ static Oid SECP384R1("1.3.132.0.34");
Validator::Validator(Face* face)
: m_face(face)
, m_wantDirectCertFetch(false)
{
}
Validator::Validator(Face& face)
: m_face(&face)
: Validator(&face)
{
}
@ -311,6 +310,12 @@ Validator::afterCheckPolicy(const std::vector<shared_ptr<ValidationRequest>>& ne
}
for (shared_ptr<ValidationRequest> step : nextSteps) {
if (m_wantDirectCertFetch && step->m_requesterFaceId != 0) {
Interest directFetchInterest(step->m_interest);
directFetchInterest.refreshNonce();
directFetchInterest.setTag(make_shared<lp::NextHopFaceIdTag>(step->m_requesterFaceId));
m_face->expressInterest(directFetchInterest, nullptr, nullptr, nullptr);
}
m_face->expressInterest(step->m_interest,
bind(&Validator::onData, this, _1, _2, step),
bind(&Validator::onNack, this, _1, _2,
@ -322,5 +327,11 @@ Validator::afterCheckPolicy(const std::vector<shared_ptr<ValidationRequest>>& ne
}
}
void
Validator::setDirectCertFetchEnabled(bool isEnabled)
{
m_wantDirectCertFetch = isEnabled;
}
} // namespace security
} // namespace ndn

27
src/security/validator.hpp

@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2016 Regents of the University of California.
* Copyright (c) 2013-2017 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@ -17,9 +17,6 @@
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*
* @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
* @author Jeff Thompson <jefft0@remap.ucla.edu>
*/
#ifndef NDN_SECURITY_VALIDATOR_HPP
@ -100,6 +97,27 @@ public:
validate(interest, onValidated, onValidationFailed, 0);
}
/**
* @brief Enable or disable the direct certificate fetch feature.
*
* When enabled, the validator will attempt to fetch the certificate that signs an Interest from
* the sender of that Interest, as identified by IncomingFaceId field, in addition to fetching
* from the infrastructure.
*
* Prior to enabling this feature, the application must enable NextHopFaceId privilege on the face
* used by this validator.
*
* @note Current implementation can only fetch the Interest signer certificate from the
* Interest sender; the issuer certificate of that certificate is only fetched from the
* infrastructure.
*
* @note Currently, this feature can only be used with ValidatorConfig.
*
* @param isEnabled Set true to enable the feature or false to disable.
*/
void
setDirectCertFetchEnabled(bool isEnabled);
/*****************************************
* verifySignature method set *
*****************************************/
@ -329,6 +347,7 @@ protected:
protected:
Face* m_face;
bool m_wantDirectCertFetch;
};
} // namespace security

153
tests/unit-tests/security/validator-config.t.cpp

@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2016 Regents of the University of California.
* Copyright (c) 2013-2017 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@ -22,12 +22,14 @@
#include "security/validator-config.hpp"
#include "security/key-chain.hpp"
#include "security/signing-helpers.hpp"
#include "util/io.hpp"
#include "util/scheduler.hpp"
#include "util/dummy-client-face.hpp"
#include "lp/tags.hpp"
#include "lp/nack.hpp"
#include <boost/asio.hpp>
#include <boost/logic/tribool.hpp>
#include "identity-management-fixture.hpp"
#include "../identity-management-time-fixture.hpp"
@ -1224,7 +1226,6 @@ BOOST_FIXTURE_TEST_CASE(Nrd, FacesFixture)
Name root("/TestValidatorConfig");
BOOST_REQUIRE(saveIdentityCertificate(root, "trust-anchor-8.cert", true));
Name sld("/TestValidatorConfig/Nrd-1");
BOOST_REQUIRE(addIdentity(sld));
advanceClocks(time::milliseconds(100));
@ -1486,6 +1487,152 @@ BOOST_FIXTURE_TEST_CASE(TrustAnchorDir, DirTestFixture)
advanceClocks(time::milliseconds(10), 20);
}
class DirectCertFetchFixture : public IdentityManagementTimeFixture
{
public:
DirectCertFetchFixture()
: clientFace(io, m_keyChain, {true, true})
, validationResult(boost::logic::indeterminate)
{
BOOST_REQUIRE(addIdentity(ca));
BOOST_REQUIRE(saveIdentityCertificate(ca, "trust-anchor-1.cert", true));
BOOST_REQUIRE(addSubCertificate(user, ca));
userCertName = m_keyChain.getDefaultCertificateNameForIdentity(user);
userCert = m_keyChain.getCertificate(userCertName);
}
protected:
void
runTest(const std::function<void(const Interest&, const Interest&)> respond)
{
optional<Interest> directInterest;
optional<Interest> infrastructureInterest;
clientFace.onSendInterest.connect([&] (const Interest& interest) {
const Name& interestName = interest.getName();
if (interestName == userCert->getName().getPrefix(-1)) {
auto nextHopFaceIdTag = interest.getTag<lp::NextHopFaceIdTag>();
if (nextHopFaceIdTag != nullptr) {
BOOST_CHECK(!directInterest);
directInterest = interest;
}
else {
BOOST_CHECK(!infrastructureInterest);
infrastructureInterest = interest;
}
if (static_cast<bool>(directInterest) && static_cast<bool>(infrastructureInterest)) {
io.post([directInterest, infrastructureInterest, respond] {
respond(directInterest.value(), infrastructureInterest.value());
});
directInterest = nullopt;
infrastructureInterest = nullopt;
}
}
});
const boost::filesystem::path CONFIG_PATH =
(boost::filesystem::current_path() / std::string("unit-test-direct.conf"));
ValidatorConfig validator(&clientFace);
validator.load(CONFIG, CONFIG_PATH.c_str());
validator.setDirectCertFetchEnabled(true);
shared_ptr<Interest> interest = make_shared<Interest>(interestName);
interest->setTag(make_shared<lp::IncomingFaceIdTag>(123));
BOOST_CHECK_NO_THROW(m_keyChain.sign(*interest, security::signingByIdentity(user)));
validator.validate(*interest,
[&] (const shared_ptr<const Interest>&) {
BOOST_CHECK(boost::logic::indeterminate(validationResult));
validationResult = true;
},
[&] (const shared_ptr<const Interest>&, const std::string& s) {
BOOST_CHECK(boost::logic::indeterminate(validationResult));
validationResult = false;
});
advanceClocks(time::milliseconds(200), 60);
BOOST_CHECK(!boost::logic::indeterminate(validationResult));
}
public:
util::DummyClientFace clientFace;
const Name ca = Name("/DirectCertFetch");
const Name user = Name("/DirectCertFetch/user");
const Name interestName = Name("/DirectCertFetch/user/tag-interest");
const std::string CONFIG = R"_TEXT_(
rule
{
id "RuleForInterest"
for interest
checker
{
type hierarchical
sig-type rsa-sha256
}
}
rule
{
id "RuleForData"
for data
filter
{
type name
regex ^<>*$
}
checker
{
type customized
sig-type rsa-sha256
key-locator
{
type name
regex ^<>*$
}
}
}
trust-anchor
{
type file
file-name "trust-anchor-1.cert"
}
)_TEXT_";
boost::logic::tribool validationResult;
Name userCertName;
shared_ptr<v1::IdentityCertificate> userCert;
};
BOOST_FIXTURE_TEST_SUITE(DirectCertFetch, DirectCertFetchFixture)
BOOST_AUTO_TEST_CASE(CertFetchSuccess)
{
runTest([this] (const Interest& directInterest, const Interest& infrastructureInterest) {
this->clientFace.receive(*userCert);
});
BOOST_CHECK_EQUAL(validationResult, true);
}
BOOST_AUTO_TEST_CASE(CertFetchTimeout)
{
// In this test case, certificate request would time out
runTest([this] (const Interest& directInterest, const Interest& infrastructureInterest) { });
BOOST_CHECK_EQUAL(validationResult, false);
}
BOOST_AUTO_TEST_CASE(CertFetchNack)
{
runTest([this] (const Interest& directInterest, const Interest& infrastructureInterest) {
lp::Nack nackInfrastructureInterest(infrastructureInterest);
nackInfrastructureInterest.setHeader(lp::NackHeader().setReason(lp::NackReason::NO_ROUTE));
this->clientFace.receive(nackInfrastructureInterest);
});
BOOST_CHECK_EQUAL(validationResult, false);
}
BOOST_AUTO_TEST_SUITE_END() // DirectCertFetch
BOOST_AUTO_TEST_SUITE_END() // TestValidatorConfig
BOOST_AUTO_TEST_SUITE_END() // Security

Loading…
Cancel
Save