blob: 1eea45e1d2fa12c70936bee0d5d0edba14fd665e [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
Yingdi Yu21157162014-02-28 13:02:34 -080016INIT_LOGGER("ndn.ValidatorRegex");
Yingdi Yu6ac97982014-01-30 14:49:21 -080017
18using namespace std;
19
Yingdi Yufc40d872014-02-18 12:56:04 -080020namespace ndn {
Yingdi Yu6ac97982014-01-30 14:49:21 -080021
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070022const shared_ptr<CertificateCache> ValidatorRegex::DEFAULT_CERTIFICATE_CACHE;
Yingdi Yu6ac97982014-01-30 14:49:21 -080023
Yingdi Yu96e64062014-04-15 19:57:33 -070024ValidatorRegex::ValidatorRegex(Face& face,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070025 shared_ptr<CertificateCache> certificateCache,
26 const int stepLimit)
Yingdi Yu6ac97982014-01-30 14:49:21 -080027 : Validator(face)
28 , m_stepLimit(stepLimit)
29 , m_certificateCache(certificateCache)
30{
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070031 if (!static_cast<bool>(m_certificateCache))
Yingdi Yu96e64062014-04-15 19:57:33 -070032 m_certificateCache = make_shared<CertificateCacheTtl>(m_face.ioService());
33}
34
35ValidatorRegex::ValidatorRegex(const shared_ptr<Face>& face,
36 shared_ptr<CertificateCache> certificateCache,
37 const int stepLimit)
38 : Validator(*face)
39 , m_stepLimit(stepLimit)
40 , m_certificateCache(certificateCache)
41{
42 if (!static_cast<bool>(m_certificateCache))
43 m_certificateCache = make_shared<CertificateCacheTtl>(m_face.ioService());
Yingdi Yu6ac97982014-01-30 14:49:21 -080044}
45
46void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070047ValidatorRegex::onCertificateValidated(const shared_ptr<const Data>& signCertificate,
48 const shared_ptr<const Data>& data,
49 const OnDataValidated& onValidated,
50 const OnDataValidationFailed& onValidationFailed)
Yingdi Yu6ac97982014-01-30 14:49:21 -080051{
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070052 shared_ptr<IdentityCertificate> certificate =
53 make_shared<IdentityCertificate>(boost::cref(*signCertificate));
54
55 if (!certificate->isTooLate() && !certificate->isTooEarly())
Yingdi Yu6ac97982014-01-30 14:49:21 -080056 {
57 m_certificateCache->insertCertificate(certificate);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070058
59 if (verifySignature(*data, certificate->getPublicKeyInfo()))
Yingdi Yu40587c02014-02-21 16:40:48 -080060 return onValidated(data);
61 else
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070062 return onValidationFailed(data,
63 "Cannot verify signature: " +
64 data->getName().toUri());
Yingdi Yu6ac97982014-01-30 14:49:21 -080065 }
66 else
67 {
Yingdi Yufc40d872014-02-18 12:56:04 -080068 _LOG_DEBUG("Wrong validity:");
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070069 return onValidationFailed(data,
70 "Signing certificate " +
71 signCertificate->getName().toUri() +
72 " is no longer valid.");
Yingdi Yu6ac97982014-01-30 14:49:21 -080073 }
74}
75
76void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070077ValidatorRegex::onCertificateValidationFailed(const shared_ptr<const Data>& signCertificate,
Yingdi Yu40587c02014-02-21 16:40:48 -080078 const string& failureInfo,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070079 const shared_ptr<const Data>& data,
80 const OnDataValidationFailed& onValidationFailed)
81{
82 onValidationFailed(data, failureInfo);
83}
Yingdi Yu6ac97982014-01-30 14:49:21 -080084
85void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070086ValidatorRegex::checkPolicy(const Data& data,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070087 int nSteps,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070088 const OnDataValidated& onValidated,
89 const OnDataValidationFailed& onValidationFailed,
90 vector<shared_ptr<ValidationRequest> >& nextSteps)
Yingdi Yu6ac97982014-01-30 14:49:21 -080091{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070092 if (m_stepLimit == nSteps)
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070093 return onValidationFailed(data.shared_from_this(),
94 "Maximum steps of validation reached: " +
95 data.getName().toUri());
Yingdi Yu40587c02014-02-21 16:40:48 -080096
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070097 for (RuleList::iterator it = m_mustFailVerify.begin();
98 it != m_mustFailVerify.end();
99 it++)
100 if ((*it)->satisfy(data))
Yingdi Yu40587c02014-02-21 16:40:48 -0800101 return onValidationFailed(data.shared_from_this(),
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700102 "Comply with mustFail policy: " +
103 data.getName().toUri());
Yingdi Yu6ac97982014-01-30 14:49:21 -0800104
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700105 for (RuleList::iterator it = m_verifyPolicies.begin();
106 it != m_verifyPolicies.end();
107 it++)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800108 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700109 if ((*it)->satisfy(data))
Yingdi Yu6ac97982014-01-30 14:49:21 -0800110 {
Yingdi Yu40587c02014-02-21 16:40:48 -0800111 try
112 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700113 SignatureSha256WithRsa sig(data.getSignature());
114
Yingdi Yu40587c02014-02-21 16:40:48 -0800115 Name keyLocatorName = sig.getKeyLocator().getName();
116 shared_ptr<const Certificate> trustedCert;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700117 if (m_trustAnchors.end() == m_trustAnchors.find(keyLocatorName))
Yingdi Yu40587c02014-02-21 16:40:48 -0800118 trustedCert = m_certificateCache->getCertificate(keyLocatorName);
Yingdi Yu6ac97982014-01-30 14:49:21 -0800119 else
Yingdi Yu40587c02014-02-21 16:40:48 -0800120 trustedCert = m_trustAnchors[keyLocatorName];
Yingdi Yu6ac97982014-01-30 14:49:21 -0800121
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700122 if (static_cast<bool>(trustedCert))
123 {
124 if (verifySignature(data, sig, trustedCert->getPublicKeyInfo()))
125 return onValidated(data.shared_from_this());
126 else
127 return onValidationFailed(data.shared_from_this(),
128 "Cannot verify signature: " +
129 data.getName().toUri());
130 }
131 else
132 {
133 // _LOG_DEBUG("KeyLocator is not trust anchor");
134 OnDataValidated onKeyValidated =
135 bind(&ValidatorRegex::onCertificateValidated, this, _1,
136 data.shared_from_this(), onValidated, onValidationFailed);
Yingdi Yu40587c02014-02-21 16:40:48 -0800137
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700138 OnDataValidationFailed onKeyValidationFailed =
139 bind(&ValidatorRegex::onCertificateValidationFailed, this, _1, _2,
140 data.shared_from_this(), onValidationFailed);
141
142 Interest interest(sig.getKeyLocator().getName());
143 shared_ptr<ValidationRequest> nextStep =
144 make_shared<ValidationRequest>(boost::cref(interest),
145 onKeyValidated,
146 onKeyValidationFailed,
147 3,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700148 nSteps + 1);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700149
150 nextSteps.push_back(nextStep);
151
152 return;
153 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800154 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700155 catch (const SignatureSha256WithRsa::Error& e)
Yingdi Yu40587c02014-02-21 16:40:48 -0800156 {
157 return onValidationFailed(data.shared_from_this(),
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700158 "Not SignatureSha256WithRsa signature: " +
159 data.getName().toUri());
160 }
161 catch (const KeyLocator::Error& e)
162 {
163 return onValidationFailed(data.shared_from_this(),
164 "Key Locator is not a name: " +
165 data.getName().toUri());
Yingdi Yu40587c02014-02-21 16:40:48 -0800166 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800167 }
168 }
169
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700170 return onValidationFailed(data.shared_from_this(),
Yingdi Yu40587c02014-02-21 16:40:48 -0800171 "No policy found for data: " + data.getName().toUri());
Yingdi Yu6ac97982014-01-30 14:49:21 -0800172}
173
Yingdi Yufc40d872014-02-18 12:56:04 -0800174} // namespace ndn