blob: 94befaa7a4958aaaf9ac481ddf4061bb97b2cbbe [file] [log] [blame]
Yingdi Yu6ac97982014-01-30 14:49:21 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07003 * Copyright (c) 2013-2014, Regents of the University of California.
4 * All rights reserved.
5 *
6 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
7 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
8 *
9 * This file licensed under New BSD License. See COPYING for detailed information about
10 * ndn-cxx library copyright, permissions, and redistribution restrictions.
11 *
12 * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
Yingdi Yu6ac97982014-01-30 14:49:21 -080013 */
14
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -080015#include "common.hpp"
16
Yingdi Yu6ac97982014-01-30 14:49:21 -080017#include "validator-regex.hpp"
18#include "signature-sha256-with-rsa.hpp"
19#include "certificate-cache-ttl.hpp"
20
21#include "../util/logging.hpp"
22
Yingdi Yu21157162014-02-28 13:02:34 -080023INIT_LOGGER("ndn.ValidatorRegex");
Yingdi Yu6ac97982014-01-30 14:49:21 -080024
25using namespace std;
26
Yingdi Yufc40d872014-02-18 12:56:04 -080027namespace ndn {
Yingdi Yu6ac97982014-01-30 14:49:21 -080028
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070029const shared_ptr<CertificateCache> ValidatorRegex::DEFAULT_CERTIFICATE_CACHE;
Yingdi Yu6ac97982014-01-30 14:49:21 -080030
Yingdi Yu96e64062014-04-15 19:57:33 -070031ValidatorRegex::ValidatorRegex(Face& face,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070032 shared_ptr<CertificateCache> certificateCache,
33 const int stepLimit)
Yingdi Yu6ac97982014-01-30 14:49:21 -080034 : Validator(face)
35 , m_stepLimit(stepLimit)
36 , m_certificateCache(certificateCache)
37{
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070038 if (!static_cast<bool>(m_certificateCache))
Yingdi Yu96e64062014-04-15 19:57:33 -070039 m_certificateCache = make_shared<CertificateCacheTtl>(m_face.ioService());
40}
41
42ValidatorRegex::ValidatorRegex(const shared_ptr<Face>& face,
43 shared_ptr<CertificateCache> certificateCache,
44 const int stepLimit)
45 : Validator(*face)
46 , m_stepLimit(stepLimit)
47 , m_certificateCache(certificateCache)
48{
49 if (!static_cast<bool>(m_certificateCache))
50 m_certificateCache = make_shared<CertificateCacheTtl>(m_face.ioService());
Yingdi Yu6ac97982014-01-30 14:49:21 -080051}
52
53void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070054ValidatorRegex::onCertificateValidated(const shared_ptr<const Data>& signCertificate,
55 const shared_ptr<const Data>& data,
56 const OnDataValidated& onValidated,
57 const OnDataValidationFailed& onValidationFailed)
Yingdi Yu6ac97982014-01-30 14:49:21 -080058{
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070059 shared_ptr<IdentityCertificate> certificate =
60 make_shared<IdentityCertificate>(boost::cref(*signCertificate));
61
62 if (!certificate->isTooLate() && !certificate->isTooEarly())
Yingdi Yu6ac97982014-01-30 14:49:21 -080063 {
64 m_certificateCache->insertCertificate(certificate);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070065
66 if (verifySignature(*data, certificate->getPublicKeyInfo()))
Yingdi Yu40587c02014-02-21 16:40:48 -080067 return onValidated(data);
68 else
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070069 return onValidationFailed(data,
70 "Cannot verify signature: " +
71 data->getName().toUri());
Yingdi Yu6ac97982014-01-30 14:49:21 -080072 }
73 else
74 {
Yingdi Yufc40d872014-02-18 12:56:04 -080075 _LOG_DEBUG("Wrong validity:");
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070076 return onValidationFailed(data,
77 "Signing certificate " +
78 signCertificate->getName().toUri() +
79 " is no longer valid.");
Yingdi Yu6ac97982014-01-30 14:49:21 -080080 }
81}
82
83void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070084ValidatorRegex::onCertificateValidationFailed(const shared_ptr<const Data>& signCertificate,
Yingdi Yu40587c02014-02-21 16:40:48 -080085 const string& failureInfo,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070086 const shared_ptr<const Data>& data,
87 const OnDataValidationFailed& onValidationFailed)
88{
89 onValidationFailed(data, failureInfo);
90}
Yingdi Yu6ac97982014-01-30 14:49:21 -080091
92void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070093ValidatorRegex::checkPolicy(const Data& data,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070094 int nSteps,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070095 const OnDataValidated& onValidated,
96 const OnDataValidationFailed& onValidationFailed,
97 vector<shared_ptr<ValidationRequest> >& nextSteps)
Yingdi Yu6ac97982014-01-30 14:49:21 -080098{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070099 if (m_stepLimit == nSteps)
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700100 return onValidationFailed(data.shared_from_this(),
101 "Maximum steps of validation reached: " +
102 data.getName().toUri());
Yingdi Yu40587c02014-02-21 16:40:48 -0800103
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700104 for (RuleList::iterator it = m_mustFailVerify.begin();
105 it != m_mustFailVerify.end();
106 it++)
107 if ((*it)->satisfy(data))
Yingdi Yu40587c02014-02-21 16:40:48 -0800108 return onValidationFailed(data.shared_from_this(),
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700109 "Comply with mustFail policy: " +
110 data.getName().toUri());
Yingdi Yu6ac97982014-01-30 14:49:21 -0800111
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700112 for (RuleList::iterator it = m_verifyPolicies.begin();
113 it != m_verifyPolicies.end();
114 it++)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800115 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700116 if ((*it)->satisfy(data))
Yingdi Yu6ac97982014-01-30 14:49:21 -0800117 {
Yingdi Yu40587c02014-02-21 16:40:48 -0800118 try
119 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700120 SignatureSha256WithRsa sig(data.getSignature());
121
Yingdi Yu40587c02014-02-21 16:40:48 -0800122 Name keyLocatorName = sig.getKeyLocator().getName();
123 shared_ptr<const Certificate> trustedCert;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700124 if (m_trustAnchors.end() == m_trustAnchors.find(keyLocatorName))
Yingdi Yu40587c02014-02-21 16:40:48 -0800125 trustedCert = m_certificateCache->getCertificate(keyLocatorName);
Yingdi Yu6ac97982014-01-30 14:49:21 -0800126 else
Yingdi Yu40587c02014-02-21 16:40:48 -0800127 trustedCert = m_trustAnchors[keyLocatorName];
Yingdi Yu6ac97982014-01-30 14:49:21 -0800128
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700129 if (static_cast<bool>(trustedCert))
130 {
131 if (verifySignature(data, sig, trustedCert->getPublicKeyInfo()))
132 return onValidated(data.shared_from_this());
133 else
134 return onValidationFailed(data.shared_from_this(),
135 "Cannot verify signature: " +
136 data.getName().toUri());
137 }
138 else
139 {
140 // _LOG_DEBUG("KeyLocator is not trust anchor");
141 OnDataValidated onKeyValidated =
142 bind(&ValidatorRegex::onCertificateValidated, this, _1,
143 data.shared_from_this(), onValidated, onValidationFailed);
Yingdi Yu40587c02014-02-21 16:40:48 -0800144
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700145 OnDataValidationFailed onKeyValidationFailed =
146 bind(&ValidatorRegex::onCertificateValidationFailed, this, _1, _2,
147 data.shared_from_this(), onValidationFailed);
148
149 Interest interest(sig.getKeyLocator().getName());
150 shared_ptr<ValidationRequest> nextStep =
151 make_shared<ValidationRequest>(boost::cref(interest),
152 onKeyValidated,
153 onKeyValidationFailed,
154 3,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700155 nSteps + 1);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700156
157 nextSteps.push_back(nextStep);
158
159 return;
160 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800161 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700162 catch (SignatureSha256WithRsa::Error& e)
Yingdi Yu40587c02014-02-21 16:40:48 -0800163 {
164 return onValidationFailed(data.shared_from_this(),
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700165 "Not SignatureSha256WithRsa signature: " +
166 data.getName().toUri());
167 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700168 catch (KeyLocator::Error& e)
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700169 {
170 return onValidationFailed(data.shared_from_this(),
171 "Key Locator is not a name: " +
172 data.getName().toUri());
Yingdi Yu40587c02014-02-21 16:40:48 -0800173 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800174 }
175 }
176
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700177 return onValidationFailed(data.shared_from_this(),
Yingdi Yu40587c02014-02-21 16:40:48 -0800178 "No policy found for data: " + data.getName().toUri());
Yingdi Yu6ac97982014-01-30 14:49:21 -0800179}
180
Yingdi Yufc40d872014-02-18 12:56:04 -0800181} // namespace ndn