blob: 0f097415b21b8262613275e757f1eb24e8f56ee6 [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
24ValidatorRegex::ValidatorRegex(shared_ptr<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>(face))
Yingdi Yu6ac97982014-01-30 14:49:21 -080032 throw Error("Face is not set!");
33
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070034 if (!static_cast<bool>(m_certificateCache))
Yingdi Yu6ac97982014-01-30 14:49:21 -080035 m_certificateCache = make_shared<CertificateCacheTtl>(m_face->ioService());
36}
37
38void
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 =
45 make_shared<IdentityCertificate>(boost::cref(*signCertificate));
46
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 Yufc40d872014-02-18 12:56:04 -080060 _LOG_DEBUG("Wrong validity:");
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070061 return onValidationFailed(data,
62 "Signing certificate " +
63 signCertificate->getName().toUri() +
64 " is no longer valid.");
Yingdi Yu6ac97982014-01-30 14:49:21 -080065 }
66}
67
68void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070069ValidatorRegex::onCertificateValidationFailed(const shared_ptr<const Data>& signCertificate,
Yingdi Yu40587c02014-02-21 16:40:48 -080070 const string& failureInfo,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070071 const shared_ptr<const Data>& data,
72 const OnDataValidationFailed& onValidationFailed)
73{
74 onValidationFailed(data, failureInfo);
75}
Yingdi Yu6ac97982014-01-30 14:49:21 -080076
77void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070078ValidatorRegex::checkPolicy(const Data& data,
79 int stepCount,
80 const OnDataValidated& onValidated,
81 const OnDataValidationFailed& onValidationFailed,
82 vector<shared_ptr<ValidationRequest> >& nextSteps)
Yingdi Yu6ac97982014-01-30 14:49:21 -080083{
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070084 if (m_stepLimit == stepCount)
85 return onValidationFailed(data.shared_from_this(),
86 "Maximum steps of validation reached: " +
87 data.getName().toUri());
Yingdi Yu40587c02014-02-21 16:40:48 -080088
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070089 for (RuleList::iterator it = m_mustFailVerify.begin();
90 it != m_mustFailVerify.end();
91 it++)
92 if ((*it)->satisfy(data))
Yingdi Yu40587c02014-02-21 16:40:48 -080093 return onValidationFailed(data.shared_from_this(),
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070094 "Comply with mustFail policy: " +
95 data.getName().toUri());
Yingdi Yu6ac97982014-01-30 14:49:21 -080096
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070097 for (RuleList::iterator it = m_verifyPolicies.begin();
98 it != m_verifyPolicies.end();
99 it++)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800100 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700101 if ((*it)->satisfy(data))
Yingdi Yu6ac97982014-01-30 14:49:21 -0800102 {
Yingdi Yu40587c02014-02-21 16:40:48 -0800103 try
104 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700105 SignatureSha256WithRsa sig(data.getSignature());
106
Yingdi Yu40587c02014-02-21 16:40:48 -0800107 Name keyLocatorName = sig.getKeyLocator().getName();
108 shared_ptr<const Certificate> trustedCert;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700109 if (m_trustAnchors.end() == m_trustAnchors.find(keyLocatorName))
Yingdi Yu40587c02014-02-21 16:40:48 -0800110 trustedCert = m_certificateCache->getCertificate(keyLocatorName);
Yingdi Yu6ac97982014-01-30 14:49:21 -0800111 else
Yingdi Yu40587c02014-02-21 16:40:48 -0800112 trustedCert = m_trustAnchors[keyLocatorName];
Yingdi Yu6ac97982014-01-30 14:49:21 -0800113
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700114 if (static_cast<bool>(trustedCert))
115 {
116 if (verifySignature(data, sig, trustedCert->getPublicKeyInfo()))
117 return onValidated(data.shared_from_this());
118 else
119 return onValidationFailed(data.shared_from_this(),
120 "Cannot verify signature: " +
121 data.getName().toUri());
122 }
123 else
124 {
125 // _LOG_DEBUG("KeyLocator is not trust anchor");
126 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 =
136 make_shared<ValidationRequest>(boost::cref(interest),
137 onKeyValidated,
138 onKeyValidationFailed,
139 3,
140 stepCount + 1);
141
142 nextSteps.push_back(nextStep);
143
144 return;
145 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800146 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700147 catch (const 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 }
153 catch (const KeyLocator::Error& e)
154 {
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