blob: 5f92436070bb46586af1ecdb1a9ac50ee96a7c7b [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
Yingdi Yu6ac97982014-01-30 14:49:21 -080021using namespace std;
22
Yingdi Yufc40d872014-02-18 12:56:04 -080023namespace ndn {
Yingdi Yu6ac97982014-01-30 14:49:21 -080024
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070025const shared_ptr<CertificateCache> ValidatorRegex::DEFAULT_CERTIFICATE_CACHE;
Yingdi Yu6ac97982014-01-30 14:49:21 -080026
Yingdi Yu96e64062014-04-15 19:57:33 -070027ValidatorRegex::ValidatorRegex(Face& face,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070028 shared_ptr<CertificateCache> certificateCache,
29 const int stepLimit)
Yingdi Yu6ac97982014-01-30 14:49:21 -080030 : Validator(face)
31 , m_stepLimit(stepLimit)
32 , m_certificateCache(certificateCache)
33{
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070034 if (!static_cast<bool>(m_certificateCache))
Alexander Afanasyevb67090a2014-04-29 22:31:01 -070035 m_certificateCache = make_shared<CertificateCacheTtl>(ref(m_face.getIoService()));
Yingdi Yu96e64062014-04-15 19:57:33 -070036}
37
Yingdi Yu6ac97982014-01-30 14:49:21 -080038void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070039ValidatorRegex::onCertificateValidated(const shared_ptr<const Data>& signCertificate,
40 const shared_ptr<const Data>& data,
41 const OnDataValidated& onValidated,
42 const OnDataValidationFailed& onValidationFailed)
Yingdi Yu6ac97982014-01-30 14:49:21 -080043{
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070044 shared_ptr<IdentityCertificate> certificate =
Alexander Afanasyevf73f0632014-05-12 18:02:37 -070045 make_shared<IdentityCertificate>(*signCertificate);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070046
47 if (!certificate->isTooLate() && !certificate->isTooEarly())
Yingdi Yu6ac97982014-01-30 14:49:21 -080048 {
49 m_certificateCache->insertCertificate(certificate);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070050
51 if (verifySignature(*data, certificate->getPublicKeyInfo()))
Yingdi Yu40587c02014-02-21 16:40:48 -080052 return onValidated(data);
53 else
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070054 return onValidationFailed(data,
55 "Cannot verify signature: " +
56 data->getName().toUri());
Yingdi Yu6ac97982014-01-30 14:49:21 -080057 }
58 else
59 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070060 return onValidationFailed(data,
61 "Signing certificate " +
62 signCertificate->getName().toUri() +
63 " is no longer valid.");
Yingdi Yu6ac97982014-01-30 14:49:21 -080064 }
65}
66
67void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070068ValidatorRegex::onCertificateValidationFailed(const shared_ptr<const Data>& signCertificate,
Yingdi Yu40587c02014-02-21 16:40:48 -080069 const string& failureInfo,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070070 const shared_ptr<const Data>& data,
71 const OnDataValidationFailed& onValidationFailed)
72{
73 onValidationFailed(data, failureInfo);
74}
Yingdi Yu6ac97982014-01-30 14:49:21 -080075
76void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070077ValidatorRegex::checkPolicy(const Data& data,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070078 int nSteps,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070079 const OnDataValidated& onValidated,
80 const OnDataValidationFailed& onValidationFailed,
81 vector<shared_ptr<ValidationRequest> >& nextSteps)
Yingdi Yu6ac97982014-01-30 14:49:21 -080082{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070083 if (m_stepLimit == nSteps)
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070084 return onValidationFailed(data.shared_from_this(),
85 "Maximum steps of validation reached: " +
86 data.getName().toUri());
Yingdi Yu40587c02014-02-21 16:40:48 -080087
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070088 for (RuleList::iterator it = m_mustFailVerify.begin();
89 it != m_mustFailVerify.end();
90 it++)
91 if ((*it)->satisfy(data))
Yingdi Yu40587c02014-02-21 16:40:48 -080092 return onValidationFailed(data.shared_from_this(),
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070093 "Comply with mustFail policy: " +
94 data.getName().toUri());
Yingdi Yu6ac97982014-01-30 14:49:21 -080095
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070096 for (RuleList::iterator it = m_verifyPolicies.begin();
97 it != m_verifyPolicies.end();
98 it++)
Yingdi Yu6ac97982014-01-30 14:49:21 -080099 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700100 if ((*it)->satisfy(data))
Yingdi Yu6ac97982014-01-30 14:49:21 -0800101 {
Yingdi Yu40587c02014-02-21 16:40:48 -0800102 try
103 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700104 SignatureSha256WithRsa sig(data.getSignature());
105
Yingdi Yu40587c02014-02-21 16:40:48 -0800106 Name keyLocatorName = sig.getKeyLocator().getName();
107 shared_ptr<const Certificate> trustedCert;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700108 if (m_trustAnchors.end() == m_trustAnchors.find(keyLocatorName))
Yingdi Yu40587c02014-02-21 16:40:48 -0800109 trustedCert = m_certificateCache->getCertificate(keyLocatorName);
Yingdi Yu6ac97982014-01-30 14:49:21 -0800110 else
Yingdi Yu40587c02014-02-21 16:40:48 -0800111 trustedCert = m_trustAnchors[keyLocatorName];
Yingdi Yu6ac97982014-01-30 14:49:21 -0800112
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700113 if (static_cast<bool>(trustedCert))
114 {
115 if (verifySignature(data, sig, trustedCert->getPublicKeyInfo()))
116 return onValidated(data.shared_from_this());
117 else
118 return onValidationFailed(data.shared_from_this(),
119 "Cannot verify signature: " +
120 data.getName().toUri());
121 }
122 else
123 {
Alexander Afanasyevfc7d33a2014-05-12 18:04:51 -0700124 // KeyLocator is not a trust anchor
125
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700126 OnDataValidated onKeyValidated =
127 bind(&ValidatorRegex::onCertificateValidated, this, _1,
128 data.shared_from_this(), onValidated, onValidationFailed);
Yingdi Yu40587c02014-02-21 16:40:48 -0800129
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700130 OnDataValidationFailed onKeyValidationFailed =
131 bind(&ValidatorRegex::onCertificateValidationFailed, this, _1, _2,
132 data.shared_from_this(), onValidationFailed);
133
134 Interest interest(sig.getKeyLocator().getName());
135 shared_ptr<ValidationRequest> nextStep =
Alexander Afanasyevf73f0632014-05-12 18:02:37 -0700136 make_shared<ValidationRequest>(interest,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700137 onKeyValidated,
138 onKeyValidationFailed,
139 3,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700140 nSteps + 1);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700141
142 nextSteps.push_back(nextStep);
143
144 return;
145 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800146 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700147 catch (SignatureSha256WithRsa::Error& e)
Yingdi Yu40587c02014-02-21 16:40:48 -0800148 {
149 return onValidationFailed(data.shared_from_this(),
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700150 "Not SignatureSha256WithRsa signature: " +
151 data.getName().toUri());
152 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700153 catch (KeyLocator::Error& e)
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700154 {
155 return onValidationFailed(data.shared_from_this(),
156 "Key Locator is not a name: " +
157 data.getName().toUri());
Yingdi Yu40587c02014-02-21 16:40:48 -0800158 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800159 }
160 }
161
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700162 return onValidationFailed(data.shared_from_this(),
Yingdi Yu40587c02014-02-21 16:40:48 -0800163 "No policy found for data: " + data.getName().toUri());
Yingdi Yu6ac97982014-01-30 14:49:21 -0800164}
165
Yingdi Yufc40d872014-02-18 12:56:04 -0800166} // namespace ndn