blob: 396ee8fc0c2e5589b8822e62877acf84de46e81e [file] [log] [blame]
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/**
* Copyright (C) 2013 Regents of the University of California.
* See COPYING for copyright and distribution information.
*/
#include "command-interest-validator.hpp"
namespace ndn
{
const ssize_t CommandInterestValidator::POS_SIG_VALUE = -1;
const ssize_t CommandInterestValidator::POS_SIG_INFO = -2;
const ssize_t CommandInterestValidator::POS_RANDOM_VAL = -3;
const ssize_t CommandInterestValidator::POS_TIMESTAMP = -4;
const int64_t CommandInterestValidator::GRACE_INTERVAL = 3000;
void
CommandInterestValidator::checkPolicy (const Interest& interest,
int stepCount,
const OnInterestValidated &onValidated,
const OnInterestValidationFailed &onValidationFailed,
std::vector<shared_ptr<ValidationRequest> > &nextSteps)
{
try{
Name interestName = interest.getName();
Signature signature(interestName.get(POS_SIG_INFO).blockFromValue(),
interestName.get(POS_SIG_VALUE).blockFromValue());
SignatureSha256WithRsa sig(signature);
const Name & keyLocatorName = sig.getKeyLocator().getName();
Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
//Check if command is in the trusted scope
bool inScope = false;
std::list<SecRuleSpecific>::iterator scopeIt = m_trustScopeForInterest.begin();
for(; scopeIt != m_trustScopeForInterest.end(); scopeIt++)
{
if(scopeIt->satisfy(interestName, keyName))
{
inScope = true;
break;
}
}
if(inScope == false)
{
onValidationFailed(interest.shared_from_this());
return;
}
//Check if timestamp is valid
uint64_t timestamp = interestName.get(POS_TIMESTAMP).toNumber();
uint64_t current = static_cast<uint64_t>(time::now()/1000000);
std::map<Name, uint64_t>::const_iterator timestampIt = m_lastTimestamp.find(keyName);
if(timestampIt == m_lastTimestamp.end())
{
if(timestamp > (current + m_graceInterval) || (timestamp + m_graceInterval) < current)
{
onValidationFailed(interest.shared_from_this());
return;
}
}
else if(m_lastTimestamp[keyName] >= timestamp)
{
onValidationFailed(interest.shared_from_this());
return;
}
//Check if signature can be verified
Name signedName = interestName.getPrefix(-1);
Buffer signedBlob = Buffer(signedName.wireEncode().value(), signedName.wireEncode().value_size()); //These two lines could be optimized
if(!Validator::verifySignature(signedBlob.buf(), signedBlob.size(), sig, m_trustAnchorsForInterest[keyName]))
{
onValidationFailed(interest.shared_from_this());
return;
}
m_lastTimestamp[keyName] = timestamp;
onValidated(interest.shared_from_this());
return;
}catch(...){
onValidationFailed(interest.shared_from_this());
}
}
}//ndn