blob: d22d55bf737883c21dc85b64d896cc6441f46bb5 [file] [log] [blame]
Yingdi Yufa4ce792014-02-06 18:09:22 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2013, Regents of the University of California
4 * Yingdi Yu
5 *
6 * BSD license, See the LICENSE file for more information
7 *
8 * Author: Yingdi Yu <yingdi@cs.ucla.edu>
9 */
10
11#include "validator-invitation.h"
12
13#include "logging.h"
14
15using namespace std;
16using namespace ndn;
17
18INIT_LOGGER("ValidatorInvitation");
19
20namespace chronos{
21
22const shared_ptr<CertificateCache> ValidatorInvitation::DefaultCertificateCache = shared_ptr<CertificateCache>();
23
24ValidatorInvitation::ValidatorInvitation(shared_ptr<Face> face,
25 const string& chatroomName,
26 const Name& signingIdentity,
27 shared_ptr<CertificateCache> certificateCache,
28 int stepLimit)
29 : Validator(face)
30 , m_stepLimit(stepLimit)
31 , m_certificateCache(certificateCache)
32 , m_chatroomName(chatroomName)
33 , m_signingIdentity(signingIdentity)
34{
35 m_invitationRule = make_shared<SecRuleRelative>("^<ndn><broadcast><chronos><invitation>([^<chatroom>]*)<chatroom>",
36 "^([^<KEY>]*)<KEY>(<>*)[<dsk-.*><ksk-.*>]<ID-CERT>$",
37 "==", "\\1", "\\1\\2", true);
38
39 m_dskRule = make_shared<SecRuleRelative>("^([^<KEY>]*)<KEY><dsk-.*><ID-CERT><>$",
40 "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
41 "==", "\\1", "\\1\\2", true);
42}
43
44void
45ValidatorInvitation::checkPolicy (const shared_ptr<const Data>& data,
46 int stepCount,
47 const OnDataValidated& onValidated,
48 const OnDataValidationFailed& onValidationFailed,
49 vector<shared_ptr<ValidationRequest> >& nextSteps)
50{
51 if(m_stepLimit == stepCount)
52 {
53 _LOG_DEBUG("reach the maximum steps of verification");
54 onValidationFailed(data);
55 return;
56 }
57
58 try{
59 SignatureSha256WithRsa sig(data->getSignature());
60 const Name & keyLocatorName = sig.getKeyLocator().getName();
61 const uint8_t* buf = data->wireEncode().wire();
62 const size_t size = data->wireEncode().size();
63
64 if(m_invitationRule->satisfy(data->getName(), keyLocatorName))
65 processSignature(buf, size,
66 sig, keyLocatorName,
67 bind(onValidated, data),
68 bind(onValidationFailed, data),
69 stepCount,
70 nextSteps);
71
72 if(m_dskRule->satisfy(data->getName(), keyLocatorName))
73 processFinalSignature(buf, size,
74 sig, keyLocatorName,
75 bind(onValidated, data),
76 bind(onValidationFailed, data));
77
78 }catch(...){
79 onValidationFailed(data);
80 return;
81 }
82}
83
84void
85ValidatorInvitation::checkPolicy (const shared_ptr<const Interest>& interest,
86 int stepCount,
87 const OnInterestValidated& onValidated,
88 const OnInterestValidationFailed& onValidationFailed,
89 vector<shared_ptr<ValidationRequest> >& nextSteps)
90{
91 try{
92 Name interestName = interest->getName();
93
94 Block signatureBlock = interestName.get(-1).blockFromValue();
95 Block signatureInfo = interestName.get(-2).blockFromValue();
96 Signature signature(signatureInfo, signatureBlock);
97
98 SignatureSha256WithRsa sig(signature);
99 const Name & keyLocatorName = sig.getKeyLocator().getName();
100
101 Name signedName = interestName.getPrefix(-1);
102 Buffer signedBlob = Buffer(signedName.wireEncode().value(), signedName.wireEncode().value_size());
103
104 processSignature(signedBlob.buf(), signedBlob.size(),
105 sig, keyLocatorName,
106 bind(onValidated, interest),
107 bind(onValidationFailed, interest),
108 stepCount,
109 nextSteps);
110
111 }catch(...){
112 onValidationFailed(interest);
113 return;
114 }
115
116}
117
118void
119ValidatorInvitation::processSignature (const uint8_t* buf,
120 const size_t size,
121 const SignatureSha256WithRsa& signature,
122 const Name& keyLocatorName,
123 const OnValidated& onValidated,
124 const OnValidationFailed& onValidationFailed,
125 int stepCount,
126 vector<shared_ptr<ValidationRequest> >& nextSteps)
127{
128 try{
129 Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
130
131 if(m_trustAnchors.find(keyName) != m_trustAnchors.end())
132 {
133 if(Validator::verifySignature(buf, size, signature, m_trustAnchors[keyName]))
134 onValidated();
135 else
136 onValidationFailed();
137 return;
138 }
139
140 if(static_cast<bool>(m_certificateCache))
141 {
142 shared_ptr<const IdentityCertificate> trustedCert = m_certificateCache->getCertificate(keyLocatorName);
143 if(static_cast<bool>(trustedCert)){
144 if(Validator::verifySignature(buf, size, signature, trustedCert->getPublicKeyInfo()))
145 onValidated();
146 else
147 onValidationFailed();
148 return;
149 }
150 }
151
152 OnDataValidated onKeyLocatorValidated =
153 bind(&ValidatorInvitation::onDskKeyLocatorValidated,
154 this, _1, buf, size, signature, onValidated, onValidationFailed);
155
156 OnDataValidationFailed onKeyLocatorValidationFailed =
157 bind(&ValidatorInvitation::onDskKeyLocatorValidationFailed,
158 this, _1, onValidationFailed);
159
160 Interest interest(keyLocatorName);
161 interest.setMustBeFresh(true);
162
163 shared_ptr<ValidationRequest> nextStep = make_shared<ValidationRequest>
164 (interest, onKeyLocatorValidated, onKeyLocatorValidationFailed, 0, stepCount + 1);
165
166 nextSteps.push_back(nextStep);
167 return;
168 }catch(...){
169 onValidationFailed();
170 return;
171 }
172}
173
174void
175ValidatorInvitation::processFinalSignature (const uint8_t* buf,
176 const size_t size,
177 const SignatureSha256WithRsa& signature,
178 const Name& keyLocatorName,
179 const OnValidated& onValidated,
180 const OnValidationFailed& onValidationFailed)
181{
182 try{
183 Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
184
185 if(m_trustAnchors.end() != m_trustAnchors.find(keyName) && Validator::verifySignature(buf, size, signature, m_trustAnchors[keyName]))
186 onValidated();
187 else
188 onValidationFailed();
189 return;
190 }catch(...){
191 onValidationFailed();
192 return;
193 }
194}
195
196
197void
198ValidatorInvitation::onDskKeyLocatorValidated(const shared_ptr<const Data>& certData,
199 const uint8_t* buf,
200 const size_t size,
201 const SignatureSha256WithRsa& signature,
202 const OnValidated& onValidated,
203 const OnValidationFailed& onValidationFailed)
204{
205 shared_ptr<IdentityCertificate> certificate = make_shared<IdentityCertificate>(*certData);
206
207 if(!certificate->isTooLate() && !certificate->isTooEarly())
208 {
209 Name certName = certificate->getName().getPrefix(-1);
210 m_dskCertificates[certName] = certificate;
211
212 if(Validator::verifySignature(buf, size, signature, certificate->getPublicKeyInfo()))
213 {
214 onValidated();
215 return;
216 }
217 }
218
219 onValidationFailed();
220 return;
221}
222
223void
224ValidatorInvitation::onDskKeyLocatorValidationFailed(const shared_ptr<const Data>& certData,
225 const OnValidationFailed& onValidationFailed)
226{ onValidationFailed(); }
227
228}//chronos