Skip to content
This repository has been archived by the owner on Mar 19, 2021. It is now read-only.

Commit

Permalink
ccnx: Verification seems to work
Browse files Browse the repository at this point in the history
Change-Id: I988f4cefbb954444dcdb989a9295e3b491203206
  • Loading branch information
Zhenkai Zhu authored and cawka committed Aug 15, 2013
1 parent d5d99be commit 203dfd2
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 10 deletions.
27 changes: 23 additions & 4 deletions ccnx/ccnx-verifier.cpp
Expand Up @@ -22,6 +22,7 @@
#include "ccnx-verifier.h"
#include "ccnx-wrapper.h"

INIT_LOGGER ("Ccnx.Verifier");
namespace Ccnx {

static const size_t ROOT_KEY_DIGEST_LEN = 32; // SHA-256
Expand All @@ -42,6 +43,7 @@ Verifier::~Verifier()
bool
Verifier::verify(const PcoPtr &pco, double maxWait)
{
_LOG_TRACE("Verifying content [" << pco->name() << "]");
HashPtr publisherPublicKeyDigest = pco->publisherPublicKeyDigest();

{
Expand All @@ -67,17 +69,21 @@ Verifier::verify(const PcoPtr &pco, double maxWait)
Name keyName = pco->keyName();
int keyNameSize = keyName.size();

if (keyNameSize == 0)
if (keyNameSize < 2)
{
_LOG_ERROR("Key name is empty or has too few components.");
return false;
}

// for keys, we have to make sure key name is strictly prefix of the content name
if (pco->type() == ParsedContentObject::KEY)
{
Name contentName = pco->name();
if (keyNameSize >= contentName.size() || contentName.getPartialName(0, keyNameSize) != keyName)
// when checking for prefix, do not include the hash in the key name (which is the last component)
Name keyNamePrefix = keyName.getPartialName(0, keyNameSize - 1);
if (keyNamePrefix.size() >= contentName.size() || contentName.getPartialName(0, keyNamePrefix.size()) != keyNamePrefix)
{
_LOG_ERROR("Key name prefix [" << keyNamePrefix << "] is not the prefix of content name [" << contentName << "]");
return false;
}
}
Expand All @@ -93,10 +99,11 @@ Verifier::verify(const PcoPtr &pco, double maxWait)
selectors.childSelector(Selectors::RIGHT)
.interestLifetime(maxWait);

PcoPtr keyObject = m_ccnx->get(keyName, selectors);
PcoPtr metaObject = m_ccnx->get(metaName, selectors);
PcoPtr keyObject = m_ccnx->get(keyName, selectors, maxWait);
PcoPtr metaObject = m_ccnx->get(metaName, selectors, maxWait);
if (!keyObject || !metaObject )
{
_LOG_ERROR("can not fetch key or meta");
return false;
}

Expand All @@ -106,18 +113,21 @@ Verifier::verify(const PcoPtr &pco, double maxWait)
// make sure key and meta are signed using the same key
if (publisherKeyHashInKeyObject->IsZero() || ! (*publisherKeyHashInKeyObject == *publisherKeyHashInMetaObject))
{
_LOG_ERROR("Key and Meta not signed by the same publisher");
return false;
}

CertPtr cert = boost::make_shared<Cert>(keyObject, metaObject);
if (cert->validity() != Cert::WITHIN_VALID_TIME_SPAN)
{
_LOG_ERROR("Certificate is not valid, validity status is : " << cert->validity());
return false;
}

// check pco is actually signed by this key (i.e. we don't trust the publisherPublicKeyDigest given by ccnx c lib)
if (! (*pco->publisherPublicKeyDigest() == cert->keyDigest()))
{
_LOG_ERROR("key digest does not match the publisher public key digest of the content object");
return false;
}

Expand All @@ -132,6 +142,7 @@ Verifier::verify(const PcoPtr &pco, double maxWait)
// can not verify key or can not verify meta
if (!verify(keyObject, maxWait) || !verify(metaObject, maxWait))
{
_LOG_ERROR("Can not verify key or meta");
return false;
}
}
Expand All @@ -144,6 +155,14 @@ Verifier::verify(const PcoPtr &pco, double maxWait)
}

pco->verifySignature(cert);
if (pco->verified())
{
_LOG_TRACE("[" << pco->name() << "] VERIFIED.");
}
else
{
_LOG_ERROR("[" << pco->name() << "] CANNOT BE VERIFIED.");
}
return pco->verified();
}

Expand Down
8 changes: 5 additions & 3 deletions ccnx/ccnx-wrapper.cpp
Expand Up @@ -705,7 +705,7 @@ CcnxWrapper::getLocalPrefix ()
}

bool
CcnxWrapper::verifyKey(PcoPtr &pco, double maxWait)
CcnxWrapper::verify(PcoPtr &pco, double maxWait)
{
return m_verifier->verify(pco, maxWait);
}
Expand All @@ -726,18 +726,20 @@ struct GetState
PcoPtr
WaitForResult ()
{
//_LOG_TRACE("GetState::WaitForResult start");
boost::unique_lock<boost::mutex> lock (m_mutex);
m_cond.timed_wait (lock, m_maxWait);
//_LOG_TRACE("GetState::WaitForResult finish");

return m_retval;
}

void
DataCallback (Name name, PcoPtr pco)
{
m_retval = pco;

//_LOG_TRACE("GetState::DataCallback, Name [" << name << "]");
boost::unique_lock<boost::mutex> lock (m_mutex);
m_retval = pco;
m_cond.notify_one ();
}

Expand Down
2 changes: 1 addition & 1 deletion ccnx/ccnx-wrapper.h
Expand Up @@ -94,7 +94,7 @@ class CcnxWrapper
putToCcnd (const Bytes &contentObject);

bool
verifyKey(PcoPtr &pco, double maxWait = 0.5 /*seconds*/);
verify(PcoPtr &pco, double maxWait = 1 /*seconds*/);

PcoPtr
get (const Name &interest, const Selectors &selector = Selectors(), double maxWait = 4.0/*seconds*/);
Expand Down
7 changes: 5 additions & 2 deletions test/test-ccnx-wrapper.cc
Expand Up @@ -65,10 +65,12 @@ void dataCallback(const Name &name, Ccnx::PcoPtr pco)
void encapCallback(const Name &name, Ccnx::PcoPtr pco)
{
cout << " in encap data callback" << endl;
BOOST_CHECK(!c1->verify(pco));
cout << "++++++++++++++++++ Outer content couldn't be verified, which is expected." << endl;
PcoPtr npco = make_shared<ParsedContentObject> (*(pco->contentPtr()));
g_dataCallback_counter ++;
BOOST_CHECK(npco);
//BOOST_CHECK(c1->checkPcoIntegrity(npco));
BOOST_CHECK(c1->verify(npco));
}

void
Expand Down Expand Up @@ -211,11 +213,12 @@ BOOST_AUTO_TEST_CASE (TestUnsigned)
c1->publishUnsignedData(Name(n2), head(content), content.size(), 1);
Closure encapClosure(bind(encapCallback, _1, _2), bind(timeout, _1, _2, _3));
c2->sendInterest(Name(n2), encapClosure);
usleep(200000);
usleep(4000000);
BOOST_CHECK_EQUAL(g_dataCallback_counter, 2);
teardown();
}


/*
BOOST_AUTO_TEST_CASE (CcnxWrapperUnsigningTest)
{
Expand Down

0 comments on commit 203dfd2

Please sign in to comment.