blob: 23d2b10fe87d4b439490454992f14c538cb653f1 [file] [log] [blame]
Yingdi Yu1ec26de2013-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
Yingdi Yu93adb1a2014-01-16 10:30:26 -080011#include "sec-policy-chrono-chat-invitation.h"
Yingdi Yuf8f572d2014-01-13 11:19:47 -080012#include <ndn-cpp/security/verifier.hpp>
Yingdi Yu93adb1a2014-01-16 10:30:26 -080013#include <ndn-cpp/security/signature-sha256-with-rsa.hpp>
Yingdi Yu978b3ae2013-10-23 11:50:51 -070014
Yingdi Yu1ec26de2013-10-22 16:59:43 -070015#include "logging.h"
16
17using namespace std;
18using namespace ndn;
Yingdi Yu76dd8002013-12-24 11:16:32 +080019using namespace ndn::ptr_lib;
Yingdi Yu1ec26de2013-10-22 16:59:43 -070020
Yingdi Yu93adb1a2014-01-16 10:30:26 -080021INIT_LOGGER("SecPolicyChronoChatInvitation");
Yingdi Yu1ec26de2013-10-22 16:59:43 -070022
Yingdi Yu93adb1a2014-01-16 10:30:26 -080023SecPolicyChronoChatInvitation::SecPolicyChronoChatInvitation(const string& chatroomName,
Yingdi Yue35bdb82013-11-07 11:32:40 -080024 const Name& signingIdentity,
Yingdi Yu76dd8002013-12-24 11:16:32 +080025 int stepLimit)
Yingdi Yu7989eb22013-10-31 17:38:22 -070026 : m_chatroomName(chatroomName)
Yingdi Yue35bdb82013-11-07 11:32:40 -080027 , m_signingIdentity(signingIdentity)
Yingdi Yu7989eb22013-10-31 17:38:22 -070028 , m_stepLimit(stepLimit)
Yingdi Yu1ec26de2013-10-22 16:59:43 -070029{
Yingdi Yu93adb1a2014-01-16 10:30:26 -080030 m_invitationPolicyRule = make_shared<SecRuleIdentity>("^<ndn><broadcast><chronos><invitation>([^<chatroom>]*)<chatroom>",
Yingdi Yu76dd8002013-12-24 11:16:32 +080031 "^([^<KEY>]*)<KEY>(<>*)[<dsk-.*><ksk-.*>]<ID-CERT>$",
32 "==", "\\1", "\\1\\2", true);
Yingdi Yu7989eb22013-10-31 17:38:22 -070033
Yingdi Yu76dd8002013-12-24 11:16:32 +080034 m_kskRegex = make_shared<Regex>("^([^<KEY>]*)<KEY>(<>*<ksk-.*>)<ID-CERT><>$", "\\1\\2");
Yingdi Yu9b34b1f2013-11-01 17:37:51 -070035
Yingdi Yu93adb1a2014-01-16 10:30:26 -080036 m_dskRule = make_shared<SecRuleIdentity>("^([^<KEY>]*)<KEY><dsk-.*><ID-CERT><>$",
Yingdi Yu76dd8002013-12-24 11:16:32 +080037 "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
38 "==", "\\1", "\\1\\2", true);
Yingdi Yu7989eb22013-10-31 17:38:22 -070039
Yingdi Yu76dd8002013-12-24 11:16:32 +080040 m_keyNameRegex = make_shared<Regex>("^([^<KEY>]*)<KEY>(<>*<ksk-.*>)<ID-CERT>$", "\\1\\2");
Yingdi Yu7989eb22013-10-31 17:38:22 -070041}
Yingdi Yu978b3ae2013-10-23 11:50:51 -070042
Yingdi Yu93adb1a2014-01-16 10:30:26 -080043SecPolicyChronoChatInvitation::~SecPolicyChronoChatInvitation()
Yingdi Yu7989eb22013-10-31 17:38:22 -070044{}
Yingdi Yu1ec26de2013-10-22 16:59:43 -070045
46bool
Yingdi Yu93adb1a2014-01-16 10:30:26 -080047SecPolicyChronoChatInvitation::skipVerifyAndTrust (const Data& data)
Yingdi Yu7989eb22013-10-31 17:38:22 -070048{ return false; }
Yingdi Yu1ec26de2013-10-22 16:59:43 -070049
50bool
Yingdi Yu93adb1a2014-01-16 10:30:26 -080051SecPolicyChronoChatInvitation::requireVerify (const Data& data)
Yingdi Yu7989eb22013-10-31 17:38:22 -070052{ return true; }
Yingdi Yu1ec26de2013-10-22 16:59:43 -070053
Yingdi Yu76dd8002013-12-24 11:16:32 +080054shared_ptr<ValidationRequest>
Yingdi Yu93adb1a2014-01-16 10:30:26 -080055SecPolicyChronoChatInvitation::checkVerificationPolicy(const shared_ptr<Data>& data,
Yingdi Yu76dd8002013-12-24 11:16:32 +080056 int stepCount,
57 const OnVerified& onVerified,
58 const OnVerifyFailed& onVerifyFailed)
Yingdi Yu1ec26de2013-10-22 16:59:43 -070059{
60 if(m_stepLimit == stepCount)
61 {
Yingdi Yue35bdb82013-11-07 11:32:40 -080062 _LOG_ERROR("Reach the maximum steps of verification!");
Yingdi Yu76dd8002013-12-24 11:16:32 +080063 onVerifyFailed(data);
Yingdi Yu93adb1a2014-01-16 10:30:26 -080064 return shared_ptr<ValidationRequest>();
Yingdi Yu1ec26de2013-10-22 16:59:43 -070065 }
66
Yingdi Yuf8f572d2014-01-13 11:19:47 -080067 try{
68 SignatureSha256WithRsa sig(data->getSignature());
Yingdi Yu1ec26de2013-10-22 16:59:43 -070069
Yingdi Yuf8f572d2014-01-13 11:19:47 -080070 const Name & keyLocatorName = sig.getKeyLocator().getName();
Yingdi Yu1ec26de2013-10-22 16:59:43 -070071
Yingdi Yuf8f572d2014-01-13 11:19:47 -080072 if(m_invitationPolicyRule->satisfy(*data))
73 {
74 // Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
75 // map<Name, PublicKey>::iterator it = m_trustAnchors.find(keyName);
76 // if(m_trustAnchors.end() != it)
77 // {
78 // if(Sha256WithRsaHandler::verifySignature(*data, it->second))
79 // onVerified(data);
80 // else
81 // onVerifyFailed(data);
Yingdi Yu1ec26de2013-10-22 16:59:43 -070082
Yingdi Yu93adb1a2014-01-16 10:30:26 -080083 // return shared_ptr<ValidationRequest>();
Yingdi Yuf8f572d2014-01-13 11:19:47 -080084 // }
Yingdi Yu9b34b1f2013-11-01 17:37:51 -070085
Yingdi Yuf8f572d2014-01-13 11:19:47 -080086 shared_ptr<const Certificate> trustedCert = m_certificateCache.getCertificate(keyLocatorName);
Yingdi Yu1ec26de2013-10-22 16:59:43 -070087
Yingdi Yu93adb1a2014-01-16 10:30:26 -080088 if(static_cast<bool>(trustedCert)){
Yingdi Yuf8f572d2014-01-13 11:19:47 -080089 if(Verifier::verifySignature(*data, sig, trustedCert->getPublicKeyInfo()))
90 onVerified(data);
Yingdi Yu9b34b1f2013-11-01 17:37:51 -070091 else
Yingdi Yu76dd8002013-12-24 11:16:32 +080092 onVerifyFailed(data);
Yingdi Yuf8f572d2014-01-13 11:19:47 -080093
Yingdi Yu93adb1a2014-01-16 10:30:26 -080094 return shared_ptr<ValidationRequest>();
Yingdi Yu9b34b1f2013-11-01 17:37:51 -070095 }
Yingdi Yu9b34b1f2013-11-01 17:37:51 -070096
Yingdi Yu93adb1a2014-01-16 10:30:26 -080097 OnVerified recursiveVerifiedCallback = boost::bind(&SecPolicyChronoChatInvitation::onDskCertificateVerified,
Yingdi Yuf8f572d2014-01-13 11:19:47 -080098 this,
99 _1,
100 data,
101 onVerified,
102 onVerifyFailed);
103
Yingdi Yu93adb1a2014-01-16 10:30:26 -0800104 OnVerifyFailed recursiveUnverifiedCallback = boost::bind(&SecPolicyChronoChatInvitation::onDskCertificateVerifyFailed,
Yingdi Yuf8f572d2014-01-13 11:19:47 -0800105 this,
106 _1,
107 data,
108 onVerifyFailed);
Yingdi Yu1ec26de2013-10-22 16:59:43 -0700109
Yingdi Yu1ec26de2013-10-22 16:59:43 -0700110
Yingdi Yuf8f572d2014-01-13 11:19:47 -0800111 shared_ptr<Interest> interest = make_shared<Interest>(keyLocatorName);
112
113 shared_ptr<ValidationRequest> nextStep = make_shared<ValidationRequest>(interest,
114 recursiveVerifiedCallback,
115 recursiveUnverifiedCallback,
116 0,
117 stepCount + 1);
118 return nextStep;
119 }
120
121 if(m_kskRegex->match(data->getName()))
122 {
123 Name keyName = m_kskRegex->expand();
124 map<Name, PublicKey>::iterator it = m_trustAnchors.find(keyName);
125 if(m_trustAnchors.end() != it)
126 {
127 IdentityCertificate identityCertificate(*data);
128 if(it->second == identityCertificate.getPublicKeyInfo())
129 {
130 onVerified(data);
131 }
132 else
133 onVerifyFailed(data);
134 }
Yingdi Yu978b3ae2013-10-23 11:50:51 -0700135 else
Yingdi Yu76dd8002013-12-24 11:16:32 +0800136 onVerifyFailed(data);
Yingdi Yu1ec26de2013-10-22 16:59:43 -0700137
Yingdi Yu93adb1a2014-01-16 10:30:26 -0800138 return shared_ptr<ValidationRequest>();
Yingdi Yuf8f572d2014-01-13 11:19:47 -0800139 }
140
141 if(m_dskRule->satisfy(*data))
142 {
143 m_keyNameRegex->match(keyLocatorName);
144 Name keyName = m_keyNameRegex->expand();
145
146 if(m_trustAnchors.end() != m_trustAnchors.find(keyName))
147 if(Verifier::verifySignature(*data, sig, m_trustAnchors[keyName]))
148 onVerified(data);
149 else
150 onVerifyFailed(data);
151 else
152 onVerifyFailed(data);
153
Yingdi Yu93adb1a2014-01-16 10:30:26 -0800154 return shared_ptr<ValidationRequest>();
Yingdi Yuf8f572d2014-01-13 11:19:47 -0800155 }
156 }catch(SignatureSha256WithRsa::Error &e){
157 _LOG_DEBUG("checkVerificationPolicy " << e.what());
158 onVerifyFailed(data);
Yingdi Yu93adb1a2014-01-16 10:30:26 -0800159 return shared_ptr<ValidationRequest>();
Yingdi Yuf8f572d2014-01-13 11:19:47 -0800160 }catch(KeyLocator::Error &e){
161 _LOG_DEBUG("checkVerificationPolicy " << e.what());
162 onVerifyFailed(data);
Yingdi Yu93adb1a2014-01-16 10:30:26 -0800163 return shared_ptr<ValidationRequest>();
Yingdi Yuf8f572d2014-01-13 11:19:47 -0800164 }
Yingdi Yu978b3ae2013-10-23 11:50:51 -0700165
Yingdi Yu76dd8002013-12-24 11:16:32 +0800166 onVerifyFailed(data);
Yingdi Yu93adb1a2014-01-16 10:30:26 -0800167 return shared_ptr<ValidationRequest>();
Yingdi Yu1ec26de2013-10-22 16:59:43 -0700168}
169
Yingdi Yu1ec26de2013-10-22 16:59:43 -0700170bool
Yingdi Yu93adb1a2014-01-16 10:30:26 -0800171SecPolicyChronoChatInvitation::checkSigningPolicy(const Name& dataName,
Yingdi Yu76dd8002013-12-24 11:16:32 +0800172 const Name& certificateName)
Yingdi Yu1ec26de2013-10-22 16:59:43 -0700173{
Yingdi Yu7989eb22013-10-31 17:38:22 -0700174 return true;
Yingdi Yu1ec26de2013-10-22 16:59:43 -0700175}
Yingdi Yu7989eb22013-10-31 17:38:22 -0700176
Yingdi Yu1ec26de2013-10-22 16:59:43 -0700177Name
Yingdi Yu93adb1a2014-01-16 10:30:26 -0800178SecPolicyChronoChatInvitation::inferSigningIdentity(const Name& dataName)
Yingdi Yu1ec26de2013-10-22 16:59:43 -0700179{
Yingdi Yue35bdb82013-11-07 11:32:40 -0800180 return m_signingIdentity;
Yingdi Yu1ec26de2013-10-22 16:59:43 -0700181}
182
183void
Yingdi Yu93adb1a2014-01-16 10:30:26 -0800184SecPolicyChronoChatInvitation::addTrustAnchor(const EndorseCertificate& selfEndorseCertificate)
Yingdi Yu76dd8002013-12-24 11:16:32 +0800185{ m_trustAnchors.insert(pair <Name, PublicKey > (selfEndorseCertificate.getPublicKeyName(), selfEndorseCertificate.getPublicKeyInfo())); }
Yingdi Yu7989eb22013-10-31 17:38:22 -0700186
187
188// void
Yingdi Yu93adb1a2014-01-16 10:30:26 -0800189// SecPolicyChronoChatInvitation::addChatDataRule(const Name& prefix,
Yingdi Yu7989eb22013-10-31 17:38:22 -0700190// const IdentityCertificate identityCertificate)
191// {
192// Name dataPrefix = prefix;
193// dataPrefix.append("chronos").append(m_chatroomName);
194// Ptr<Regex> dataRegex = Regex::fromName(prefix);
195// Name certName = identityCertificate.getName();
196// Name signerName = certName.getPrefix(certName.size()-1);
197// Ptr<Regex> signerRegex = Regex::fromName(signerName, true);
198
199// ChatPolicyRule rule(dataRegex, signerRegex);
200// map<Name, ChatPolicyRule>::iterator it = m_chatDataRules.find(dataPrefix);
201// if(it != m_chatDataRules.end())
202// it->second = rule;
203// else
204// m_chatDataRules.insert(pair <Name, ChatPolicyRule > (dataPrefix, rule));
205// }
206
207
208void
Yingdi Yu93adb1a2014-01-16 10:30:26 -0800209SecPolicyChronoChatInvitation::onDskCertificateVerified(const shared_ptr<Data>& certData,
Yingdi Yu76dd8002013-12-24 11:16:32 +0800210 shared_ptr<Data> originalData,
211 const OnVerified& onVerified,
212 const OnVerifyFailed& onVerifyFailed)
Yingdi Yu7989eb22013-10-31 17:38:22 -0700213{
Yingdi Yu76dd8002013-12-24 11:16:32 +0800214 shared_ptr<IdentityCertificate> certificate = make_shared<IdentityCertificate>(*certData);
Yingdi Yu7989eb22013-10-31 17:38:22 -0700215
216 if(!certificate->isTooLate() && !certificate->isTooEarly())
217 {
Yingdi Yu76dd8002013-12-24 11:16:32 +0800218 Name certName = certificate->getName().getPrefix(-1);
219 map<Name, shared_ptr<IdentityCertificate> >::iterator it = m_dskCertificates.find(certName);
Yingdi Yu7989eb22013-10-31 17:38:22 -0700220 if(it == m_dskCertificates.end())
Yingdi Yu76dd8002013-12-24 11:16:32 +0800221 m_dskCertificates.insert(pair <Name, shared_ptr<IdentityCertificate> > (certName, certificate));
Yingdi Yu7989eb22013-10-31 17:38:22 -0700222
Yingdi Yuf8f572d2014-01-13 11:19:47 -0800223 if(Verifier::verifySignature(*originalData, originalData->getSignature(), certificate->getPublicKeyInfo()))
Yingdi Yu7989eb22013-10-31 17:38:22 -0700224 {
Yingdi Yu76dd8002013-12-24 11:16:32 +0800225 onVerified(originalData);
Yingdi Yu7989eb22013-10-31 17:38:22 -0700226 return;
227 }
228 }
229 else
230 {
Yingdi Yu76dd8002013-12-24 11:16:32 +0800231 onVerifyFailed(originalData);
Yingdi Yu7989eb22013-10-31 17:38:22 -0700232 return;
233 }
234}
235
236void
Yingdi Yu93adb1a2014-01-16 10:30:26 -0800237SecPolicyChronoChatInvitation::onDskCertificateVerifyFailed(const shared_ptr<Data>& certData,
Yingdi Yu76dd8002013-12-24 11:16:32 +0800238 shared_ptr<Data> originalData,
239 const OnVerifyFailed& onVerifyFailed)
240{ onVerifyFailed(originalData); }
Yingdi Yu7989eb22013-10-31 17:38:22 -0700241
Yingdi Yu76dd8002013-12-24 11:16:32 +0800242shared_ptr<IdentityCertificate>
Yingdi Yu93adb1a2014-01-16 10:30:26 -0800243SecPolicyChronoChatInvitation::getValidatedDskCertificate(const ndn::Name& certName)
Yingdi Yu7989eb22013-10-31 17:38:22 -0700244{
Yingdi Yu76dd8002013-12-24 11:16:32 +0800245 map<Name, shared_ptr<IdentityCertificate> >::iterator it = m_dskCertificates.find(certName);
Yingdi Yu7989eb22013-10-31 17:38:22 -0700246 if(m_dskCertificates.end() != it)
247 return it->second;
248 else
Yingdi Yu93adb1a2014-01-16 10:30:26 -0800249 return shared_ptr<IdentityCertificate>();
Yingdi Yu76dd8002013-12-24 11:16:32 +0800250}