blob: 58c9fccf97e03dad4176b92e8dfcbf890bd2005b [file] [log] [blame]
Yingdi Yuea5f1c62013-10-22 16:59:43 -07001/* -*- 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 "invitation-policy-manager.h"
Yingdi Yu53eb8a72013-10-23 11:50:51 -070012
Yingdi Yu42f66462013-10-31 17:38:22 -070013#include <ndn.cxx/security/cache/ttl-certificate-cache.h>
Yingdi Yu53eb8a72013-10-23 11:50:51 -070014
Yingdi Yuea5f1c62013-10-22 16:59:43 -070015#include "logging.h"
16
17using namespace std;
18using namespace ndn;
19using namespace ndn::security;
20
21INIT_LOGGER("InvitationPolicyManager");
22
Yingdi Yu42f66462013-10-31 17:38:22 -070023InvitationPolicyManager::InvitationPolicyManager(const string& chatroomName,
Yingdi Yub35b8652013-11-07 11:32:40 -080024 const Name& signingIdentity,
25 int stepLimit,
26 Ptr<CertificateCache> certificateCache)
Yingdi Yu42f66462013-10-31 17:38:22 -070027 : m_chatroomName(chatroomName)
Yingdi Yub35b8652013-11-07 11:32:40 -080028 , m_signingIdentity(signingIdentity)
Yingdi Yu42f66462013-10-31 17:38:22 -070029 , m_stepLimit(stepLimit)
Yingdi Yuea5f1c62013-10-22 16:59:43 -070030 , m_certificateCache(certificateCache)
Yingdi Yuea5f1c62013-10-22 16:59:43 -070031{
Yingdi Yu42f66462013-10-31 17:38:22 -070032 if(m_certificateCache == NULL)
33 m_certificateCache = Ptr<TTLCertificateCache>(new TTLCertificateCache());
34
35 m_invitationPolicyRule = Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^<ndn><broadcast><chronos><invitation>([^<chatroom>]*)<chatroom>",
Yingdi Yued8cfc42013-11-01 17:37:51 -070036 "^([^<KEY>]*)<KEY>(<>*)[<dsk-.*><ksk-.*>]<ID-CERT>$",
37 "==", "\\1", "\\1\\2", true));
38
39 m_kskRegex = Ptr<Regex>(new Regex("^([^<KEY>]*)<KEY>(<>*<ksk-.*>)<ID-CERT><>$", "\\1\\2"));
Yingdi Yu42f66462013-10-31 17:38:22 -070040
41 m_dskRule = Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^([^<KEY>]*)<KEY><dsk-.*><ID-CERT><>$",
42 "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
Yingdi Yuea5f1c62013-10-22 16:59:43 -070043 "==", "\\1", "\\1\\2", true));
Yingdi Yu53eb8a72013-10-23 11:50:51 -070044
Yingdi Yu42f66462013-10-31 17:38:22 -070045 m_keyNameRegex = Ptr<Regex>(new Regex("^([^<KEY>]*)<KEY>(<>*<ksk-.*>)<ID-CERT>$", "\\1\\2"));
46}
Yingdi Yu53eb8a72013-10-23 11:50:51 -070047
Yingdi Yu42f66462013-10-31 17:38:22 -070048InvitationPolicyManager::~InvitationPolicyManager()
49{}
Yingdi Yuea5f1c62013-10-22 16:59:43 -070050
51bool
Yingdi Yu42f66462013-10-31 17:38:22 -070052InvitationPolicyManager::skipVerifyAndTrust (const Data& data)
53{ return false; }
Yingdi Yuea5f1c62013-10-22 16:59:43 -070054
55bool
Yingdi Yu42f66462013-10-31 17:38:22 -070056InvitationPolicyManager::requireVerify (const Data& data)
57{ return true; }
Yingdi Yuea5f1c62013-10-22 16:59:43 -070058
59Ptr<ValidationRequest>
60InvitationPolicyManager::checkVerificationPolicy(Ptr<Data> data,
Yingdi Yu42f66462013-10-31 17:38:22 -070061 const int& stepCount,
62 const DataCallback& verifiedCallback,
63 const UnverifiedCallback& unverifiedCallback)
Yingdi Yuea5f1c62013-10-22 16:59:43 -070064{
65 if(m_stepLimit == stepCount)
66 {
Yingdi Yub35b8652013-11-07 11:32:40 -080067 _LOG_ERROR("Reach the maximum steps of verification!");
Yingdi Yuea5f1c62013-10-22 16:59:43 -070068 unverifiedCallback(data);
69 return NULL;
70 }
71
72 Ptr<const signature::Sha256WithRsa> sha256sig = boost::dynamic_pointer_cast<const signature::Sha256WithRsa> (data->getSignature());
73
74 if(KeyLocator::KEYNAME != sha256sig->getKeyLocator().getType())
75 {
Yingdi Yub35b8652013-11-07 11:32:40 -080076 _LOG_ERROR("KeyLocator is not name!");
Yingdi Yuea5f1c62013-10-22 16:59:43 -070077 unverifiedCallback(data);
78 return NULL;
79 }
80
81 const Name & keyLocatorName = sha256sig->getKeyLocator().getKeyName();
82
Yingdi Yu42f66462013-10-31 17:38:22 -070083 if(m_invitationPolicyRule->satisfy(*data))
84 {
Yingdi Yued8cfc42013-11-01 17:37:51 -070085 // Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
86 // map<Name, Publickey>::iterator it = m_trustAnchors.find(keyName);
87 // if(m_trustAnchors.end() != it)
88 // {
89 // if(verifySignature(*data, it->second))
90 // verifiedCallback(data);
91 // else
92 // unverifiedCallback(data);
93
94 // return NULL;
95 // }
96
Yingdi Yu42f66462013-10-31 17:38:22 -070097 Ptr<const IdentityCertificate> trustedCert = m_certificateCache->getCertificate(keyLocatorName);
Yingdi Yuea5f1c62013-10-22 16:59:43 -070098
Yingdi Yu42f66462013-10-31 17:38:22 -070099 if(NULL != trustedCert){
100 if(verifySignature(*data, trustedCert->getPublicKeyInfo()))
101 verifiedCallback(data);
102 else
103 unverifiedCallback(data);
Yingdi Yuea5f1c62013-10-22 16:59:43 -0700104
Yingdi Yu42f66462013-10-31 17:38:22 -0700105 return NULL;
106 }
Yingdi Yuea5f1c62013-10-22 16:59:43 -0700107
Yingdi Yued8cfc42013-11-01 17:37:51 -0700108 DataCallback recursiveVerifiedCallback = boost::bind(&InvitationPolicyManager::onDskCertificateVerified,
109 this,
110 _1,
111 data,
112 verifiedCallback,
113 unverifiedCallback);
114
115 UnverifiedCallback recursiveUnverifiedCallback = boost::bind(&InvitationPolicyManager::onDskCertificateUnverified,
116 this,
117 _1,
118 data,
119 unverifiedCallback);
Yingdi Yuea5f1c62013-10-22 16:59:43 -0700120
121
Yingdi Yued8cfc42013-11-01 17:37:51 -0700122 Ptr<Interest> interest = Ptr<Interest>(new Interest(keyLocatorName));
123
124 Ptr<ValidationRequest> nextStep = Ptr<ValidationRequest>(new ValidationRequest(interest,
125 recursiveVerifiedCallback,
126 recursiveUnverifiedCallback,
127 0,
128 stepCount + 1)
129 );
130 return nextStep;
131 }
132
133 if(m_kskRegex->match(data->getName()))
134 {
Yingdi Yued8cfc42013-11-01 17:37:51 -0700135 Name keyName = m_kskRegex->expand();
Yingdi Yued8cfc42013-11-01 17:37:51 -0700136 map<Name, Publickey>::iterator it = m_trustAnchors.find(keyName);
137 if(m_trustAnchors.end() != it)
138 {
Yingdi Yued8cfc42013-11-01 17:37:51 -0700139 Ptr<IdentityCertificate> identityCertificate = Ptr<IdentityCertificate>(new IdentityCertificate(*data));
140 if(it->second.getKeyBlob() == identityCertificate->getPublicKeyInfo().getKeyBlob())
141 {
Yingdi Yued8cfc42013-11-01 17:37:51 -0700142 verifiedCallback(data);
143 }
144 else
145 unverifiedCallback(data);
146 }
147 else
148 unverifiedCallback(data);
149
150 return NULL;
Yingdi Yu42f66462013-10-31 17:38:22 -0700151 }
Yingdi Yuea5f1c62013-10-22 16:59:43 -0700152
153 if(m_dskRule->satisfy(*data))
154 {
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700155 m_keyNameRegex->match(keyLocatorName);
156 Name keyName = m_keyNameRegex->expand();
Yingdi Yuea5f1c62013-10-22 16:59:43 -0700157
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700158 if(m_trustAnchors.end() != m_trustAnchors.find(keyName))
159 if(verifySignature(*data, m_trustAnchors[keyName]))
160 verifiedCallback(data);
161 else
162 unverifiedCallback(data);
Yingdi Yuea5f1c62013-10-22 16:59:43 -0700163 else
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700164 unverifiedCallback(data);
Yingdi Yuea5f1c62013-10-22 16:59:43 -0700165
166 return NULL;
167 }
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700168
169 unverifiedCallback(data);
170 return NULL;
Yingdi Yuea5f1c62013-10-22 16:59:43 -0700171}
172
Yingdi Yuea5f1c62013-10-22 16:59:43 -0700173bool
Yingdi Yu42f66462013-10-31 17:38:22 -0700174InvitationPolicyManager::checkSigningPolicy(const Name& dataName,
175 const Name& certificateName)
Yingdi Yuea5f1c62013-10-22 16:59:43 -0700176{
Yingdi Yu42f66462013-10-31 17:38:22 -0700177 return true;
Yingdi Yuea5f1c62013-10-22 16:59:43 -0700178}
Yingdi Yu42f66462013-10-31 17:38:22 -0700179
Yingdi Yuea5f1c62013-10-22 16:59:43 -0700180Name
Yingdi Yu42f66462013-10-31 17:38:22 -0700181InvitationPolicyManager::inferSigningIdentity(const Name& dataName)
Yingdi Yuea5f1c62013-10-22 16:59:43 -0700182{
Yingdi Yub35b8652013-11-07 11:32:40 -0800183 return m_signingIdentity;
Yingdi Yuea5f1c62013-10-22 16:59:43 -0700184}
185
186void
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700187InvitationPolicyManager::addTrustAnchor(const EndorseCertificate& selfEndorseCertificate)
188{ m_trustAnchors.insert(pair <Name, Publickey > (selfEndorseCertificate.getPublicKeyName(), selfEndorseCertificate.getPublicKeyInfo())); }
Yingdi Yu42f66462013-10-31 17:38:22 -0700189
190
191// void
192// InvitationPolicyManager::addChatDataRule(const Name& prefix,
193// const IdentityCertificate identityCertificate)
194// {
195// Name dataPrefix = prefix;
196// dataPrefix.append("chronos").append(m_chatroomName);
197// Ptr<Regex> dataRegex = Regex::fromName(prefix);
198// Name certName = identityCertificate.getName();
199// Name signerName = certName.getPrefix(certName.size()-1);
200// Ptr<Regex> signerRegex = Regex::fromName(signerName, true);
201
202// ChatPolicyRule rule(dataRegex, signerRegex);
203// map<Name, ChatPolicyRule>::iterator it = m_chatDataRules.find(dataPrefix);
204// if(it != m_chatDataRules.end())
205// it->second = rule;
206// else
207// m_chatDataRules.insert(pair <Name, ChatPolicyRule > (dataPrefix, rule));
208// }
209
210
211void
212InvitationPolicyManager::onDskCertificateVerified(Ptr<Data> certData,
Yingdi Yub35b8652013-11-07 11:32:40 -0800213 Ptr<Data> originalData,
214 const DataCallback& verifiedCallback,
215 const UnverifiedCallback& unverifiedCallback)
Yingdi Yu42f66462013-10-31 17:38:22 -0700216{
217 Ptr<IdentityCertificate> certificate = Ptr<IdentityCertificate>(new IdentityCertificate(*certData));
218
219 if(!certificate->isTooLate() && !certificate->isTooEarly())
220 {
221 Name certName = certificate->getName().getPrefix(certificate->getName().size()-1);
222 map<Name, Ptr<IdentityCertificate> >::iterator it = m_dskCertificates.find(certName);
223 if(it == m_dskCertificates.end())
224 m_dskCertificates.insert(pair <Name, Ptr<IdentityCertificate> > (certName, certificate));
225
226 if(verifySignature(*originalData, certificate->getPublicKeyInfo()))
227 {
228 verifiedCallback(originalData);
229 return;
230 }
231 }
232 else
233 {
234 unverifiedCallback(originalData);
235 return;
236 }
237}
238
239void
240InvitationPolicyManager::onDskCertificateUnverified(Ptr<Data> certData,
241 Ptr<Data> originalData,
242 const UnverifiedCallback& unverifiedCallback)
243{ unverifiedCallback(originalData); }
244
245Ptr<IdentityCertificate>
246InvitationPolicyManager::getValidatedDskCertificate(const ndn::Name& certName)
247{
248 map<Name, Ptr<IdentityCertificate> >::iterator it = m_dskCertificates.find(certName);
249 if(m_dskCertificates.end() != it)
250 return it->second;
251 else
252 return NULL;
253}