blob: 0885e2554b2124ce8ff7cb19de26c95ab307b022 [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 Yu64206112013-12-24 11:16:32 +080012#include "null-ptrs.h"
13#include <ndn-cpp/sha256-with-rsa-signature.hpp>
14#include <ndn-cpp/security/signature/sha256-with-rsa-handler.hpp>
Yingdi Yu53eb8a72013-10-23 11:50:51 -070015
Yingdi Yuea5f1c62013-10-22 16:59:43 -070016#include "logging.h"
17
18using namespace std;
19using namespace ndn;
Yingdi Yu64206112013-12-24 11:16:32 +080020using namespace ndn::ptr_lib;
Yingdi Yuea5f1c62013-10-22 16:59:43 -070021
22INIT_LOGGER("InvitationPolicyManager");
23
Yingdi Yu42f66462013-10-31 17:38:22 -070024InvitationPolicyManager::InvitationPolicyManager(const string& chatroomName,
Yingdi Yub35b8652013-11-07 11:32:40 -080025 const Name& signingIdentity,
Yingdi Yu64206112013-12-24 11:16:32 +080026 int stepLimit)
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{
Yingdi Yu64206112013-12-24 11:16:32 +080031 m_invitationPolicyRule = make_shared<IdentityPolicyRule>("^<ndn><broadcast><chronos><invitation>([^<chatroom>]*)<chatroom>",
32 "^([^<KEY>]*)<KEY>(<>*)[<dsk-.*><ksk-.*>]<ID-CERT>$",
33 "==", "\\1", "\\1\\2", true);
Yingdi Yu42f66462013-10-31 17:38:22 -070034
Yingdi Yu64206112013-12-24 11:16:32 +080035 m_kskRegex = make_shared<Regex>("^([^<KEY>]*)<KEY>(<>*<ksk-.*>)<ID-CERT><>$", "\\1\\2");
Yingdi Yued8cfc42013-11-01 17:37:51 -070036
Yingdi Yu64206112013-12-24 11:16:32 +080037 m_dskRule = make_shared<IdentityPolicyRule>("^([^<KEY>]*)<KEY><dsk-.*><ID-CERT><>$",
38 "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
39 "==", "\\1", "\\1\\2", true);
Yingdi Yu42f66462013-10-31 17:38:22 -070040
Yingdi Yu64206112013-12-24 11:16:32 +080041 m_keyNameRegex = make_shared<Regex>("^([^<KEY>]*)<KEY>(<>*<ksk-.*>)<ID-CERT>$", "\\1\\2");
Yingdi Yu42f66462013-10-31 17:38:22 -070042}
Yingdi Yu53eb8a72013-10-23 11:50:51 -070043
Yingdi Yu42f66462013-10-31 17:38:22 -070044InvitationPolicyManager::~InvitationPolicyManager()
45{}
Yingdi Yuea5f1c62013-10-22 16:59:43 -070046
47bool
Yingdi Yu42f66462013-10-31 17:38:22 -070048InvitationPolicyManager::skipVerifyAndTrust (const Data& data)
49{ return false; }
Yingdi Yuea5f1c62013-10-22 16:59:43 -070050
51bool
Yingdi Yu42f66462013-10-31 17:38:22 -070052InvitationPolicyManager::requireVerify (const Data& data)
53{ return true; }
Yingdi Yuea5f1c62013-10-22 16:59:43 -070054
Yingdi Yu64206112013-12-24 11:16:32 +080055shared_ptr<ValidationRequest>
56InvitationPolicyManager::checkVerificationPolicy(const shared_ptr<Data>& data,
57 int stepCount,
58 const OnVerified& onVerified,
59 const OnVerifyFailed& onVerifyFailed)
Yingdi Yuea5f1c62013-10-22 16:59:43 -070060{
61 if(m_stepLimit == stepCount)
62 {
Yingdi Yub35b8652013-11-07 11:32:40 -080063 _LOG_ERROR("Reach the maximum steps of verification!");
Yingdi Yu64206112013-12-24 11:16:32 +080064 onVerifyFailed(data);
65 return CHRONOCHAT_NULL_VALIDATIONREQUEST_PTR;
Yingdi Yuea5f1c62013-10-22 16:59:43 -070066 }
67
Yingdi Yu64206112013-12-24 11:16:32 +080068 const Sha256WithRsaSignature* sha256sig = dynamic_cast<const Sha256WithRsaSignature*> (data->getSignature());
Yingdi Yuea5f1c62013-10-22 16:59:43 -070069
Yingdi Yu64206112013-12-24 11:16:32 +080070 if(ndn_KeyLocatorType_KEYNAME != sha256sig->getKeyLocator().getType())
Yingdi Yuea5f1c62013-10-22 16:59:43 -070071 {
Yingdi Yub35b8652013-11-07 11:32:40 -080072 _LOG_ERROR("KeyLocator is not name!");
Yingdi Yu64206112013-12-24 11:16:32 +080073 onVerifyFailed(data);
74 return CHRONOCHAT_NULL_VALIDATIONREQUEST_PTR;
Yingdi Yuea5f1c62013-10-22 16:59:43 -070075 }
76
77 const Name & keyLocatorName = sha256sig->getKeyLocator().getKeyName();
78
Yingdi Yu42f66462013-10-31 17:38:22 -070079 if(m_invitationPolicyRule->satisfy(*data))
80 {
Yingdi Yued8cfc42013-11-01 17:37:51 -070081 // Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
Yingdi Yuaccbda92013-12-27 08:44:12 +080082 // map<Name, PublicKey>::iterator it = m_trustAnchors.find(keyName);
Yingdi Yued8cfc42013-11-01 17:37:51 -070083 // if(m_trustAnchors.end() != it)
84 // {
Yingdi Yuaccbda92013-12-27 08:44:12 +080085 // if(Sha256WithRsaHandler::verifySignature(*data, it->second))
86 // onVerified(data);
Yingdi Yued8cfc42013-11-01 17:37:51 -070087 // else
Yingdi Yuaccbda92013-12-27 08:44:12 +080088 // onVerifyFailed(data);
Yingdi Yued8cfc42013-11-01 17:37:51 -070089
Yingdi Yuaccbda92013-12-27 08:44:12 +080090 // return CHRONOCHAT_NULL_VALIDATIONREQUEST_PTR;
Yingdi Yued8cfc42013-11-01 17:37:51 -070091 // }
92
Yingdi Yu64206112013-12-24 11:16:32 +080093 shared_ptr<const Certificate> trustedCert = m_certificateCache.getCertificate(keyLocatorName);
Yingdi Yuea5f1c62013-10-22 16:59:43 -070094
Yingdi Yuaccbda92013-12-27 08:44:12 +080095 if(trustedCert != ndn::TCC_NULL_CERTIFICATE_PTR){
Yingdi Yu64206112013-12-24 11:16:32 +080096 if(Sha256WithRsaHandler::verifySignature(*data, trustedCert->getPublicKeyInfo()))
97 onVerified(data);
Yingdi Yu42f66462013-10-31 17:38:22 -070098 else
Yingdi Yu64206112013-12-24 11:16:32 +080099 onVerifyFailed(data);
Yingdi Yuea5f1c62013-10-22 16:59:43 -0700100
Yingdi Yu64206112013-12-24 11:16:32 +0800101 return CHRONOCHAT_NULL_VALIDATIONREQUEST_PTR;
Yingdi Yu42f66462013-10-31 17:38:22 -0700102 }
Yingdi Yuea5f1c62013-10-22 16:59:43 -0700103
Yingdi Yu64206112013-12-24 11:16:32 +0800104 OnVerified recursiveVerifiedCallback = boost::bind(&InvitationPolicyManager::onDskCertificateVerified,
105 this,
106 _1,
107 data,
108 onVerified,
109 onVerifyFailed);
Yingdi Yued8cfc42013-11-01 17:37:51 -0700110
Yingdi Yu64206112013-12-24 11:16:32 +0800111 OnVerifyFailed recursiveUnverifiedCallback = boost::bind(&InvitationPolicyManager::onDskCertificateVerifyFailed,
112 this,
113 _1,
114 data,
115 onVerifyFailed);
Yingdi Yuea5f1c62013-10-22 16:59:43 -0700116
117
Yingdi Yu64206112013-12-24 11:16:32 +0800118 shared_ptr<Interest> interest = make_shared<Interest>(keyLocatorName);
Yingdi Yued8cfc42013-11-01 17:37:51 -0700119
Yingdi Yu64206112013-12-24 11:16:32 +0800120 shared_ptr<ValidationRequest> nextStep = make_shared<ValidationRequest>(interest,
121 recursiveVerifiedCallback,
122 recursiveUnverifiedCallback,
123 0,
124 stepCount + 1);
Yingdi Yued8cfc42013-11-01 17:37:51 -0700125 return nextStep;
126 }
127
128 if(m_kskRegex->match(data->getName()))
129 {
Yingdi Yued8cfc42013-11-01 17:37:51 -0700130 Name keyName = m_kskRegex->expand();
Yingdi Yu64206112013-12-24 11:16:32 +0800131 map<Name, PublicKey>::iterator it = m_trustAnchors.find(keyName);
Yingdi Yued8cfc42013-11-01 17:37:51 -0700132 if(m_trustAnchors.end() != it)
133 {
Yingdi Yu64206112013-12-24 11:16:32 +0800134 IdentityCertificate identityCertificate(*data);
135 if(isSameKey(it->second.getKeyDer(), identityCertificate.getPublicKeyInfo().getKeyDer()))
Yingdi Yued8cfc42013-11-01 17:37:51 -0700136 {
Yingdi Yu64206112013-12-24 11:16:32 +0800137 onVerified(data);
Yingdi Yued8cfc42013-11-01 17:37:51 -0700138 }
139 else
Yingdi Yu64206112013-12-24 11:16:32 +0800140 onVerifyFailed(data);
Yingdi Yued8cfc42013-11-01 17:37:51 -0700141 }
142 else
Yingdi Yu64206112013-12-24 11:16:32 +0800143 onVerifyFailed(data);
Yingdi Yued8cfc42013-11-01 17:37:51 -0700144
Yingdi Yu64206112013-12-24 11:16:32 +0800145 return CHRONOCHAT_NULL_VALIDATIONREQUEST_PTR;
Yingdi Yu42f66462013-10-31 17:38:22 -0700146 }
Yingdi Yuea5f1c62013-10-22 16:59:43 -0700147
148 if(m_dskRule->satisfy(*data))
149 {
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700150 m_keyNameRegex->match(keyLocatorName);
151 Name keyName = m_keyNameRegex->expand();
Yingdi Yuea5f1c62013-10-22 16:59:43 -0700152
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700153 if(m_trustAnchors.end() != m_trustAnchors.find(keyName))
Yingdi Yu64206112013-12-24 11:16:32 +0800154 if(Sha256WithRsaHandler::verifySignature(*data, m_trustAnchors[keyName]))
155 onVerified(data);
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700156 else
Yingdi Yu64206112013-12-24 11:16:32 +0800157 onVerifyFailed(data);
Yingdi Yuea5f1c62013-10-22 16:59:43 -0700158 else
Yingdi Yu64206112013-12-24 11:16:32 +0800159 onVerifyFailed(data);
Yingdi Yuea5f1c62013-10-22 16:59:43 -0700160
Yingdi Yu64206112013-12-24 11:16:32 +0800161 return CHRONOCHAT_NULL_VALIDATIONREQUEST_PTR;
Yingdi Yuea5f1c62013-10-22 16:59:43 -0700162 }
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700163
Yingdi Yu64206112013-12-24 11:16:32 +0800164 onVerifyFailed(data);
165 return CHRONOCHAT_NULL_VALIDATIONREQUEST_PTR;
Yingdi Yuea5f1c62013-10-22 16:59:43 -0700166}
167
Yingdi Yuea5f1c62013-10-22 16:59:43 -0700168bool
Yingdi Yu42f66462013-10-31 17:38:22 -0700169InvitationPolicyManager::checkSigningPolicy(const Name& dataName,
Yingdi Yu64206112013-12-24 11:16:32 +0800170 const Name& certificateName)
Yingdi Yuea5f1c62013-10-22 16:59:43 -0700171{
Yingdi Yu42f66462013-10-31 17:38:22 -0700172 return true;
Yingdi Yuea5f1c62013-10-22 16:59:43 -0700173}
Yingdi Yu42f66462013-10-31 17:38:22 -0700174
Yingdi Yuea5f1c62013-10-22 16:59:43 -0700175Name
Yingdi Yu42f66462013-10-31 17:38:22 -0700176InvitationPolicyManager::inferSigningIdentity(const Name& dataName)
Yingdi Yuea5f1c62013-10-22 16:59:43 -0700177{
Yingdi Yub35b8652013-11-07 11:32:40 -0800178 return m_signingIdentity;
Yingdi Yuea5f1c62013-10-22 16:59:43 -0700179}
180
181void
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700182InvitationPolicyManager::addTrustAnchor(const EndorseCertificate& selfEndorseCertificate)
Yingdi Yu64206112013-12-24 11:16:32 +0800183{ m_trustAnchors.insert(pair <Name, PublicKey > (selfEndorseCertificate.getPublicKeyName(), selfEndorseCertificate.getPublicKeyInfo())); }
Yingdi Yu42f66462013-10-31 17:38:22 -0700184
185
186// void
187// InvitationPolicyManager::addChatDataRule(const Name& prefix,
188// const IdentityCertificate identityCertificate)
189// {
190// Name dataPrefix = prefix;
191// dataPrefix.append("chronos").append(m_chatroomName);
192// Ptr<Regex> dataRegex = Regex::fromName(prefix);
193// Name certName = identityCertificate.getName();
194// Name signerName = certName.getPrefix(certName.size()-1);
195// Ptr<Regex> signerRegex = Regex::fromName(signerName, true);
196
197// ChatPolicyRule rule(dataRegex, signerRegex);
198// map<Name, ChatPolicyRule>::iterator it = m_chatDataRules.find(dataPrefix);
199// if(it != m_chatDataRules.end())
200// it->second = rule;
201// else
202// m_chatDataRules.insert(pair <Name, ChatPolicyRule > (dataPrefix, rule));
203// }
204
205
206void
Yingdi Yu64206112013-12-24 11:16:32 +0800207InvitationPolicyManager::onDskCertificateVerified(const shared_ptr<Data>& certData,
208 shared_ptr<Data> originalData,
209 const OnVerified& onVerified,
210 const OnVerifyFailed& onVerifyFailed)
Yingdi Yu42f66462013-10-31 17:38:22 -0700211{
Yingdi Yu64206112013-12-24 11:16:32 +0800212 shared_ptr<IdentityCertificate> certificate = make_shared<IdentityCertificate>(*certData);
Yingdi Yu42f66462013-10-31 17:38:22 -0700213
214 if(!certificate->isTooLate() && !certificate->isTooEarly())
215 {
Yingdi Yu64206112013-12-24 11:16:32 +0800216 Name certName = certificate->getName().getPrefix(-1);
217 map<Name, shared_ptr<IdentityCertificate> >::iterator it = m_dskCertificates.find(certName);
Yingdi Yu42f66462013-10-31 17:38:22 -0700218 if(it == m_dskCertificates.end())
Yingdi Yu64206112013-12-24 11:16:32 +0800219 m_dskCertificates.insert(pair <Name, shared_ptr<IdentityCertificate> > (certName, certificate));
Yingdi Yu42f66462013-10-31 17:38:22 -0700220
Yingdi Yu64206112013-12-24 11:16:32 +0800221 if(Sha256WithRsaHandler::verifySignature(*originalData, certificate->getPublicKeyInfo()))
Yingdi Yu42f66462013-10-31 17:38:22 -0700222 {
Yingdi Yu64206112013-12-24 11:16:32 +0800223 onVerified(originalData);
Yingdi Yu42f66462013-10-31 17:38:22 -0700224 return;
225 }
226 }
227 else
228 {
Yingdi Yu64206112013-12-24 11:16:32 +0800229 onVerifyFailed(originalData);
Yingdi Yu42f66462013-10-31 17:38:22 -0700230 return;
231 }
232}
233
234void
Yingdi Yu64206112013-12-24 11:16:32 +0800235InvitationPolicyManager::onDskCertificateVerifyFailed(const shared_ptr<Data>& certData,
236 shared_ptr<Data> originalData,
237 const OnVerifyFailed& onVerifyFailed)
238{ onVerifyFailed(originalData); }
Yingdi Yu42f66462013-10-31 17:38:22 -0700239
Yingdi Yu64206112013-12-24 11:16:32 +0800240shared_ptr<IdentityCertificate>
Yingdi Yu42f66462013-10-31 17:38:22 -0700241InvitationPolicyManager::getValidatedDskCertificate(const ndn::Name& certName)
242{
Yingdi Yu64206112013-12-24 11:16:32 +0800243 map<Name, shared_ptr<IdentityCertificate> >::iterator it = m_dskCertificates.find(certName);
Yingdi Yu42f66462013-10-31 17:38:22 -0700244 if(m_dskCertificates.end() != it)
245 return it->second;
246 else
Yingdi Yu64206112013-12-24 11:16:32 +0800247 return CHRONOCHAT_NULL_IDENTITYCERTIFICATE_PTR;
248}
249
250
251bool
252InvitationPolicyManager::isSameKey(const Blob& keyA, const Blob& keyB)
253{
254 size_t size = keyA.size();
255
256 if(size != keyB.size())
257 return false;
258
259 const uint8_t* ap = keyA.buf();
260 const uint8_t* bp = keyB.buf();
261
262 for(int i = 0; i < size; i++)
263 {
264 if(ap[i] != bp[i])
265 return false;
266 }
267
268 return true;
Yingdi Yu42f66462013-10-31 17:38:22 -0700269}