blob: 8d6300db0d7cb47c8aa3cb33877d39018ee0c25a [file] [log] [blame]
Yingdi Yu42f66462013-10-31 17:38:22 -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 "panel-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>
15// #include <boost/bind.hpp>
Yingdi Yu42f66462013-10-31 17:38:22 -070016
17#include "logging.h"
18
19using namespace std;
20using namespace ndn;
Yingdi Yu64206112013-12-24 11:16:32 +080021using namespace ndn::ptr_lib;
Yingdi Yu42f66462013-10-31 17:38:22 -070022
23INIT_LOGGER("PanelPolicyManager");
24
Yingdi Yu64206112013-12-24 11:16:32 +080025PanelPolicyManager::PanelPolicyManager(const int & stepLimit)
Yingdi Yu42f66462013-10-31 17:38:22 -070026 : m_stepLimit(stepLimit)
Yingdi Yu64206112013-12-24 11:16:32 +080027 , m_certificateCache()
Yingdi Yu42f66462013-10-31 17:38:22 -070028{
Yingdi Yu64206112013-12-24 11:16:32 +080029 m_localPrefixRegex = make_shared<Regex>("^<local><ndn><prefix><><>$");
Yingdi Yued8cfc42013-11-01 17:37:51 -070030
Yingdi Yu64206112013-12-24 11:16:32 +080031 m_invitationDataSigningRule = make_shared<IdentityPolicyRule>("^<ndn><broadcast><chronos><invitation>([^<chatroom>]*)<chatroom>",
32 "^([^<KEY>]*)<KEY>(<>*)<><ID-CERT><>$",
33 "==", "\\1", "\\1\\2", true);
Yingdi Yu42f66462013-10-31 17:38:22 -070034
Yingdi Yu64206112013-12-24 11:16:32 +080035 m_dskRule = make_shared<IdentityPolicyRule>("^([^<KEY>]*)<KEY><dsk-.*><ID-CERT><>$",
36 "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
37 "==", "\\1", "\\1\\2", true);
Yingdi Yu8dacdf22013-11-05 23:06:43 -080038
Yingdi Yu64206112013-12-24 11:16:32 +080039 m_endorseeRule = make_shared<IdentityPolicyRule>("^([^<DNS>]*)<DNS><>*<ENDORSEE><>$",
40 "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
41 "==", "\\1", "\\1\\2", true);
Yingdi Yu8dacdf22013-11-05 23:06:43 -080042
Yingdi Yu64206112013-12-24 11:16:32 +080043 m_kskRegex = make_shared<Regex>("^([^<KEY>]*)<KEY>(<>*<ksk-.*>)<ID-CERT><>$", "\\1\\2");
Yingdi Yu42f66462013-10-31 17:38:22 -070044
Yingdi Yu64206112013-12-24 11:16:32 +080045 m_keyNameRegex = make_shared<Regex>("^([^<KEY>]*)<KEY>(<>*<ksk-.*>)<ID-CERT>$", "\\1\\2");
Yingdi Yu42f66462013-10-31 17:38:22 -070046
Yingdi Yu64206112013-12-24 11:16:32 +080047 m_signingCertificateRegex = make_shared<Regex>("^<ndn><broadcast><chronos><invitation>([^<chatroom>]*)<chatroom>", "\\1");
Yingdi Yu42f66462013-10-31 17:38:22 -070048}
49
50bool
51PanelPolicyManager::skipVerifyAndTrust (const Data & data)
52{
53 if(m_localPrefixRegex->match(data.getName()))
54 return true;
55
56 return false;
57}
58
59bool
60PanelPolicyManager::requireVerify (const Data & data)
61{
62 // if(m_invitationDataRule->matchDataName(data))
63 // return true;
Yingdi Yued8cfc42013-11-01 17:37:51 -070064 if(m_kskRegex->match(data.getName()))
65 return true;
Yingdi Yu42f66462013-10-31 17:38:22 -070066 if(m_dskRule->matchDataName(data))
67 return true;
68
Yingdi Yu8dacdf22013-11-05 23:06:43 -080069 if(m_endorseeRule->matchDataName(data))
70 return true;
71
72
Yingdi Yu42f66462013-10-31 17:38:22 -070073 return false;
74}
75
Yingdi Yu64206112013-12-24 11:16:32 +080076shared_ptr<ValidationRequest>
77PanelPolicyManager::checkVerificationPolicy(const shared_ptr<Data>& data,
78 int stepCount,
79 const OnVerified& onVerified,
80 const OnVerifyFailed& onVerifyFailed)
Yingdi Yu42f66462013-10-31 17:38:22 -070081{
Yingdi Yu42f66462013-10-31 17:38:22 -070082 if(m_stepLimit == stepCount)
83 {
Yingdi Yub35b8652013-11-07 11:32:40 -080084 _LOG_ERROR("Reach the maximum steps of verification!");
Yingdi Yu64206112013-12-24 11:16:32 +080085 onVerifyFailed(data);
86 return CHRONOCHAT_NULL_VALIDATIONREQUEST_PTR;
Yingdi Yu42f66462013-10-31 17:38:22 -070087 }
88
Yingdi Yu64206112013-12-24 11:16:32 +080089 const Sha256WithRsaSignature* sha256sig = dynamic_cast<const Sha256WithRsaSignature*>(data->getSignature());
Yingdi Yu42f66462013-10-31 17:38:22 -070090
Yingdi Yu64206112013-12-24 11:16:32 +080091 if(ndn_KeyLocatorType_KEYNAME != sha256sig->getKeyLocator().getType())
Yingdi Yu42f66462013-10-31 17:38:22 -070092 {
Yingdi Yub35b8652013-11-07 11:32:40 -080093 _LOG_ERROR("Keylocator is not name!");
Yingdi Yu64206112013-12-24 11:16:32 +080094 onVerifyFailed(data);
95 return CHRONOCHAT_NULL_VALIDATIONREQUEST_PTR;
Yingdi Yu42f66462013-10-31 17:38:22 -070096 }
97
98 const Name & keyLocatorName = sha256sig->getKeyLocator().getKeyName();
99
Yingdi Yued8cfc42013-11-01 17:37:51 -0700100 if(m_kskRegex->match(data->getName()))
101 {
Yingdi Yued8cfc42013-11-01 17:37:51 -0700102 Name keyName = m_kskRegex->expand();
Yingdi Yu64206112013-12-24 11:16:32 +0800103 map<Name, PublicKey>::iterator it = m_trustAnchors.find(keyName);
Yingdi Yued8cfc42013-11-01 17:37:51 -0700104 if(m_trustAnchors.end() != it)
105 {
Yingdi Yu6b56f092013-11-10 11:54:02 -0800106 // _LOG_DEBUG("found key!");
Yingdi Yu64206112013-12-24 11:16:32 +0800107 IdentityCertificate identityCertificate(*data);
108 if(isSameKey(it->second.getKeyDer(), identityCertificate.getPublicKeyInfo().getKeyDer()))
109 onVerified(data);
Yingdi Yued8cfc42013-11-01 17:37:51 -0700110 else
Yingdi Yu64206112013-12-24 11:16:32 +0800111 onVerifyFailed(data);
Yingdi Yued8cfc42013-11-01 17:37:51 -0700112 }
113 else
Yingdi Yu64206112013-12-24 11:16:32 +0800114 onVerifyFailed(data);
Yingdi Yu42f66462013-10-31 17:38:22 -0700115
Yingdi Yu64206112013-12-24 11:16:32 +0800116 return CHRONOCHAT_NULL_VALIDATIONREQUEST_PTR;
Yingdi Yued8cfc42013-11-01 17:37:51 -0700117 }
Yingdi Yu42f66462013-10-31 17:38:22 -0700118
119 if(m_dskRule->satisfy(*data))
120 {
121 m_keyNameRegex->match(keyLocatorName);
122 Name keyName = m_keyNameRegex->expand();
Yingdi Yu42f66462013-10-31 17:38:22 -0700123
124 if(m_trustAnchors.end() != m_trustAnchors.find(keyName))
Yingdi Yu64206112013-12-24 11:16:32 +0800125 if(Sha256WithRsaHandler::verifySignature(*data, m_trustAnchors[keyName]))
126 onVerified(data);
Yingdi Yu42f66462013-10-31 17:38:22 -0700127 else
Yingdi Yu64206112013-12-24 11:16:32 +0800128 onVerifyFailed(data);
Yingdi Yu42f66462013-10-31 17:38:22 -0700129 else
Yingdi Yu64206112013-12-24 11:16:32 +0800130 onVerifyFailed(data);
Yingdi Yu42f66462013-10-31 17:38:22 -0700131
Yingdi Yu64206112013-12-24 11:16:32 +0800132 return CHRONOCHAT_NULL_VALIDATIONREQUEST_PTR;
Yingdi Yu42f66462013-10-31 17:38:22 -0700133 }
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800134
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800135 if(m_endorseeRule->satisfy(*data))
136 {
137 m_keyNameRegex->match(keyLocatorName);
138 Name keyName = m_keyNameRegex->expand();
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800139 if(m_trustAnchors.end() != m_trustAnchors.find(keyName))
Yingdi Yu64206112013-12-24 11:16:32 +0800140 if(Sha256WithRsaHandler::verifySignature(*data, m_trustAnchors[keyName]))
141 onVerified(data);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800142 else
Yingdi Yu64206112013-12-24 11:16:32 +0800143 onVerifyFailed(data);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800144 else
Yingdi Yu64206112013-12-24 11:16:32 +0800145 onVerifyFailed(data);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800146
Yingdi Yu64206112013-12-24 11:16:32 +0800147 return CHRONOCHAT_NULL_VALIDATIONREQUEST_PTR;
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800148 }
149
Yingdi Yu42f66462013-10-31 17:38:22 -0700150 _LOG_DEBUG("Unverified!");
151
Yingdi Yu64206112013-12-24 11:16:32 +0800152 onVerifyFailed(data);
153 return CHRONOCHAT_NULL_VALIDATIONREQUEST_PTR;
Yingdi Yu42f66462013-10-31 17:38:22 -0700154}
155
Yingdi Yu42f66462013-10-31 17:38:22 -0700156bool
157PanelPolicyManager::checkSigningPolicy(const Name & dataName, const Name & certificateName)
158{
159 return m_invitationDataSigningRule->satisfy(dataName, certificateName);
160}
161
162Name
163PanelPolicyManager::inferSigningIdentity(const Name & dataName)
164{
165 if(m_signingCertificateRegex->match(dataName))
166 return m_signingCertificateRegex->expand();
167 else
168 return Name();
169}
170
171void
172PanelPolicyManager::addTrustAnchor(const EndorseCertificate& selfEndorseCertificate)
173{
Yingdi Yub35b8652013-11-07 11:32:40 -0800174 // _LOG_DEBUG("Add Anchor: " << selfEndorseCertificate.getPublicKeyName().toUri());
Yingdi Yu64206112013-12-24 11:16:32 +0800175 m_trustAnchors.insert(pair <Name, PublicKey > (selfEndorseCertificate.getPublicKeyName(), selfEndorseCertificate.getPublicKeyInfo()));
Yingdi Yu42f66462013-10-31 17:38:22 -0700176}
Yingdi Yu6b56f092013-11-10 11:54:02 -0800177
Yingdi Yu6ea54e42013-11-12 17:50:21 -0800178void
179PanelPolicyManager::removeTrustAnchor(const Name& keyName)
180{
181 m_trustAnchors.erase(keyName);
182}
183
Yingdi Yu64206112013-12-24 11:16:32 +0800184shared_ptr<PublicKey>
185PanelPolicyManager::getTrustedKey(const Name& inviterCertName)
Yingdi Yu6b56f092013-11-10 11:54:02 -0800186{
Yingdi Yu64206112013-12-24 11:16:32 +0800187 Name keyLocatorName = inviterCertName.getPrefix(-1);
Yingdi Yu6b56f092013-11-10 11:54:02 -0800188 m_keyNameRegex->match(keyLocatorName);
189 Name keyName = m_keyNameRegex->expand();
190
191 if(m_trustAnchors.end() != m_trustAnchors.find(keyName))
Yingdi Yu64206112013-12-24 11:16:32 +0800192 return make_shared<PublicKey>(m_trustAnchors[keyName]);
193 return CHRONOCHAT_NULL_PUBLICKEY_PTR;
194}
195
196bool
197PanelPolicyManager::isSameKey(const Blob& keyA, const Blob& keyB)
198{
199 size_t size = keyA.size();
200
201 if(size != keyB.size())
202 return false;
203
204 const uint8_t* ap = keyA.buf();
205 const uint8_t* bp = keyB.buf();
206
207 for(int i = 0; i < size; i++)
208 {
209 if(ap[i] != bp[i])
210 return false;
211 }
212
213 return true;
Yingdi Yu6b56f092013-11-10 11:54:02 -0800214}