blob: 4c74e79563015681860c17a4aa97366be7549389 [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))
Alexander Afanasyevb67090a2014-04-29 22:31:01 -070039 m_certificateCache = make_shared<CertificateCacheTtl>(ref(m_face.getIoService()));
Yingdi Yu96e64062014-04-15 19:57:33 -070040}
41
Yingdi Yu6ac97982014-01-30 14:49:21 -080042void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070043ValidatorRegex::onCertificateValidated(const shared_ptr<const Data>& signCertificate,
44 const shared_ptr<const Data>& data,
45 const OnDataValidated& onValidated,
46 const OnDataValidationFailed& onValidationFailed)
Yingdi Yu6ac97982014-01-30 14:49:21 -080047{
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070048 shared_ptr<IdentityCertificate> certificate =
Alexander Afanasyevf73f0632014-05-12 18:02:37 -070049 make_shared<IdentityCertificate>(*signCertificate);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070050
51 if (!certificate->isTooLate() && !certificate->isTooEarly())
Yingdi Yu6ac97982014-01-30 14:49:21 -080052 {
53 m_certificateCache->insertCertificate(certificate);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070054
55 if (verifySignature(*data, certificate->getPublicKeyInfo()))
Yingdi Yu40587c02014-02-21 16:40:48 -080056 return onValidated(data);
57 else
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070058 return onValidationFailed(data,
59 "Cannot verify signature: " +
60 data->getName().toUri());
Yingdi Yu6ac97982014-01-30 14:49:21 -080061 }
62 else
63 {
Yingdi Yufc40d872014-02-18 12:56:04 -080064 _LOG_DEBUG("Wrong validity:");
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070065 return onValidationFailed(data,
66 "Signing certificate " +
67 signCertificate->getName().toUri() +
68 " is no longer valid.");
Yingdi Yu6ac97982014-01-30 14:49:21 -080069 }
70}
71
72void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070073ValidatorRegex::onCertificateValidationFailed(const shared_ptr<const Data>& signCertificate,
Yingdi Yu40587c02014-02-21 16:40:48 -080074 const string& failureInfo,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070075 const shared_ptr<const Data>& data,
76 const OnDataValidationFailed& onValidationFailed)
77{
78 onValidationFailed(data, failureInfo);
79}
Yingdi Yu6ac97982014-01-30 14:49:21 -080080
81void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070082ValidatorRegex::checkPolicy(const Data& data,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070083 int nSteps,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070084 const OnDataValidated& onValidated,
85 const OnDataValidationFailed& onValidationFailed,
86 vector<shared_ptr<ValidationRequest> >& nextSteps)
Yingdi Yu6ac97982014-01-30 14:49:21 -080087{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070088 if (m_stepLimit == nSteps)
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070089 return onValidationFailed(data.shared_from_this(),
90 "Maximum steps of validation reached: " +
91 data.getName().toUri());
Yingdi Yu40587c02014-02-21 16:40:48 -080092
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070093 for (RuleList::iterator it = m_mustFailVerify.begin();
94 it != m_mustFailVerify.end();
95 it++)
96 if ((*it)->satisfy(data))
Yingdi Yu40587c02014-02-21 16:40:48 -080097 return onValidationFailed(data.shared_from_this(),
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070098 "Comply with mustFail policy: " +
99 data.getName().toUri());
Yingdi Yu6ac97982014-01-30 14:49:21 -0800100
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700101 for (RuleList::iterator it = m_verifyPolicies.begin();
102 it != m_verifyPolicies.end();
103 it++)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800104 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700105 if ((*it)->satisfy(data))
Yingdi Yu6ac97982014-01-30 14:49:21 -0800106 {
Yingdi Yu40587c02014-02-21 16:40:48 -0800107 try
108 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700109 SignatureSha256WithRsa sig(data.getSignature());
110
Yingdi Yu40587c02014-02-21 16:40:48 -0800111 Name keyLocatorName = sig.getKeyLocator().getName();
112 shared_ptr<const Certificate> trustedCert;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700113 if (m_trustAnchors.end() == m_trustAnchors.find(keyLocatorName))
Yingdi Yu40587c02014-02-21 16:40:48 -0800114 trustedCert = m_certificateCache->getCertificate(keyLocatorName);
Yingdi Yu6ac97982014-01-30 14:49:21 -0800115 else
Yingdi Yu40587c02014-02-21 16:40:48 -0800116 trustedCert = m_trustAnchors[keyLocatorName];
Yingdi Yu6ac97982014-01-30 14:49:21 -0800117
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700118 if (static_cast<bool>(trustedCert))
119 {
120 if (verifySignature(data, sig, trustedCert->getPublicKeyInfo()))
121 return onValidated(data.shared_from_this());
122 else
123 return onValidationFailed(data.shared_from_this(),
124 "Cannot verify signature: " +
125 data.getName().toUri());
126 }
127 else
128 {
129 // _LOG_DEBUG("KeyLocator is not trust anchor");
130 OnDataValidated onKeyValidated =
131 bind(&ValidatorRegex::onCertificateValidated, this, _1,
132 data.shared_from_this(), onValidated, onValidationFailed);
Yingdi Yu40587c02014-02-21 16:40:48 -0800133
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700134 OnDataValidationFailed onKeyValidationFailed =
135 bind(&ValidatorRegex::onCertificateValidationFailed, this, _1, _2,
136 data.shared_from_this(), onValidationFailed);
137
138 Interest interest(sig.getKeyLocator().getName());
139 shared_ptr<ValidationRequest> nextStep =
Alexander Afanasyevf73f0632014-05-12 18:02:37 -0700140 make_shared<ValidationRequest>(interest,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700141 onKeyValidated,
142 onKeyValidationFailed,
143 3,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700144 nSteps + 1);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700145
146 nextSteps.push_back(nextStep);
147
148 return;
149 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800150 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700151 catch (SignatureSha256WithRsa::Error& e)
Yingdi Yu40587c02014-02-21 16:40:48 -0800152 {
153 return onValidationFailed(data.shared_from_this(),
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700154 "Not SignatureSha256WithRsa signature: " +
155 data.getName().toUri());
156 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700157 catch (KeyLocator::Error& e)
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700158 {
159 return onValidationFailed(data.shared_from_this(),
160 "Key Locator is not a name: " +
161 data.getName().toUri());
Yingdi Yu40587c02014-02-21 16:40:48 -0800162 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800163 }
164 }
165
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700166 return onValidationFailed(data.shared_from_this(),
Yingdi Yu40587c02014-02-21 16:40:48 -0800167 "No policy found for data: " + data.getName().toUri());
Yingdi Yu6ac97982014-01-30 14:49:21 -0800168}
169
Yingdi Yufc40d872014-02-18 12:56:04 -0800170} // namespace ndn