blob: 85fb53429476695c8ca1f1e784c74bff6ac8c144 [file] [log] [blame]
Yingdi Yu6ac97982014-01-30 14:49:21 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
3 * Copyright (C) 2013 Regents of the University of California.
4 * @author: Yingdi Yu <yingdi@cs.ucla.edu>
5 * See COPYING for copyright and distribution information.
6 */
7
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -08008#include "common.hpp"
9
Yingdi Yu6ac97982014-01-30 14:49:21 -080010#include "validator-regex.hpp"
11#include "signature-sha256-with-rsa.hpp"
12#include "certificate-cache-ttl.hpp"
13
14#include "../util/logging.hpp"
15
16INIT_LOGGER("ndn::ValidatorRegex");
17
18using namespace std;
19
Yingdi Yufc40d872014-02-18 12:56:04 -080020namespace ndn {
Yingdi Yu6ac97982014-01-30 14:49:21 -080021
22const shared_ptr<CertificateCache> ValidatorRegex::DefaultCertificateCache = shared_ptr<CertificateCache>();
23
24ValidatorRegex::ValidatorRegex(shared_ptr<Face> face,
25 shared_ptr<CertificateCache> certificateCache /* = DefaultCertificateCache */,
26 const int stepLimit /* = 3 */)
27 : Validator(face)
28 , m_stepLimit(stepLimit)
29 , m_certificateCache(certificateCache)
30{
31 if(!static_cast<bool>(face))
32 throw Error("Face is not set!");
33
34 if(!static_cast<bool>(m_certificateCache))
35 m_certificateCache = make_shared<CertificateCacheTtl>(m_face->ioService());
36}
37
38void
39ValidatorRegex::onCertificateValidated(const shared_ptr<const Data> &signCertificate,
40 const shared_ptr<const Data> &data,
41 const OnDataValidated &onValidated,
42 const OnDataValidationFailed &onValidationFailed)
43{
44 shared_ptr<IdentityCertificate> certificate = make_shared<IdentityCertificate>(*signCertificate);
45
46 if(!certificate->isTooLate() && !certificate->isTooEarly())
47 {
48 m_certificateCache->insertCertificate(certificate);
49
Yingdi Yu40587c02014-02-21 16:40:48 -080050 if(verifySignature(*data, certificate->getPublicKeyInfo()))
51 return onValidated(data);
52 else
53 return onValidationFailed(data,
54 "Cannot verify signature: " + data->getName().toUri());
Yingdi Yu6ac97982014-01-30 14:49:21 -080055 }
56 else
57 {
Yingdi Yufc40d872014-02-18 12:56:04 -080058 _LOG_DEBUG("Wrong validity:");
Yingdi Yu40587c02014-02-21 16:40:48 -080059 return onValidationFailed(data,
60 "Signing certificate " + signCertificate->getName().toUri() + " is no longer valid.");
Yingdi Yu6ac97982014-01-30 14:49:21 -080061 }
62}
63
64void
65ValidatorRegex::onCertificateValidationFailed(const shared_ptr<const Data> &signCertificate,
Yingdi Yu40587c02014-02-21 16:40:48 -080066 const string& failureInfo,
Yingdi Yu6ac97982014-01-30 14:49:21 -080067 const shared_ptr<const Data> &data,
68 const OnDataValidationFailed &onValidationFailed)
Yingdi Yu40587c02014-02-21 16:40:48 -080069{ onValidationFailed(data, failureInfo); }
Yingdi Yu6ac97982014-01-30 14:49:21 -080070
71void
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080072ValidatorRegex::checkPolicy(const Data& data,
Yingdi Yu6ac97982014-01-30 14:49:21 -080073 int stepCount,
74 const OnDataValidated &onValidated,
75 const OnDataValidationFailed &onValidationFailed,
76 vector<shared_ptr<ValidationRequest> > &nextSteps)
77{
Yingdi Yu40587c02014-02-21 16:40:48 -080078 if(m_stepLimit == stepCount)
79 return onValidationFailed(data.shared_from_this(),
80 "Maximum steps of validation reached: " + data.getName().toUri());
81
Yingdi Yu6ac97982014-01-30 14:49:21 -080082 RuleList::iterator it = m_mustFailVerify.begin();
83 for(; it != m_mustFailVerify.end(); it++)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080084 if((*it)->satisfy(data))
Yingdi Yu40587c02014-02-21 16:40:48 -080085 return onValidationFailed(data.shared_from_this(),
86 "Comply with mustFail policy: " + data.getName().toUri());
Yingdi Yu6ac97982014-01-30 14:49:21 -080087
88 it = m_verifyPolicies.begin();
89 for(; it != m_verifyPolicies.end(); it++)
90 {
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080091 if((*it)->satisfy(data))
Yingdi Yu6ac97982014-01-30 14:49:21 -080092 {
Yingdi Yu40587c02014-02-21 16:40:48 -080093 try
94 {
95 SignatureSha256WithRsa sig(data.getSignature());
Yingdi Yu6ac97982014-01-30 14:49:21 -080096
Yingdi Yu40587c02014-02-21 16:40:48 -080097 Name keyLocatorName = sig.getKeyLocator().getName();
98 shared_ptr<const Certificate> trustedCert;
99 if(m_trustAnchors.end() == m_trustAnchors.find(keyLocatorName))
100 trustedCert = m_certificateCache->getCertificate(keyLocatorName);
Yingdi Yu6ac97982014-01-30 14:49:21 -0800101 else
Yingdi Yu40587c02014-02-21 16:40:48 -0800102 trustedCert = m_trustAnchors[keyLocatorName];
103
104 if(static_cast<bool>(trustedCert)){
105 if(verifySignature(data, sig, trustedCert->getPublicKeyInfo()))
106 return onValidated(data.shared_from_this());
107 else
108 return onValidationFailed(data.shared_from_this(),
109 "Cannot verify signature: " + data.getName().toUri());
110 }
111 else{
112 // _LOG_DEBUG("KeyLocator is not trust anchor");
113 OnDataValidated onKeyValidated = bind(&ValidatorRegex::onCertificateValidated, this,
114 _1, data.shared_from_this(), onValidated, onValidationFailed);
Yingdi Yu6ac97982014-01-30 14:49:21 -0800115
Yingdi Yu40587c02014-02-21 16:40:48 -0800116 OnDataValidationFailed onKeyValidationFailed = bind(&ValidatorRegex::onCertificateValidationFailed, this,
117 _1, _2, data.shared_from_this(), onValidationFailed);
Yingdi Yu6ac97982014-01-30 14:49:21 -0800118
Yingdi Yu40587c02014-02-21 16:40:48 -0800119 shared_ptr<ValidationRequest> nextStep = make_shared<ValidationRequest>(Interest(boost::cref(sig.getKeyLocator().getName())),
120 onKeyValidated,
121 onKeyValidationFailed,
122 3,
123 stepCount + 1);
124 nextSteps.push_back(nextStep);
125
126 return;
127 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800128 }
Yingdi Yu40587c02014-02-21 16:40:48 -0800129 catch(SignatureSha256WithRsa::Error &e)
130 {
131 return onValidationFailed(data.shared_from_this(),
132 "Not SignatureSha256WithRsa signature: " + data.getName().toUri());
133 }
134 catch(KeyLocator::Error &e)
135 {
136 return onValidationFailed(data.shared_from_this(),
137 "Key Locator is not a name: " + data.getName().toUri());
138 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800139 }
140 }
141
Yingdi Yu40587c02014-02-21 16:40:48 -0800142 return onValidationFailed(data.shared_from_this(),
143 "No policy found for data: " + data.getName().toUri());
Yingdi Yu6ac97982014-01-30 14:49:21 -0800144}
145
Yingdi Yufc40d872014-02-18 12:56:04 -0800146} // namespace ndn