blob: c71e023f4a3ec3950472b0b89e3e4fa92a133ef4 [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
Yingdi Yueaa84e22014-01-16 10:30:26 -080011#include "sec-policy-chrono-chat-panel.h"
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -080012#include <ndn-cpp/security/verifier.hpp>
Yingdi Yueaa84e22014-01-16 10:30:26 -080013#include <ndn-cpp/security/signature-sha256-with-rsa.hpp>
Yingdi Yu64206112013-12-24 11:16:32 +080014// #include <boost/bind.hpp>
Yingdi Yu42f66462013-10-31 17:38:22 -070015
16#include "logging.h"
17
18using namespace std;
19using namespace ndn;
Yingdi Yu64206112013-12-24 11:16:32 +080020using namespace ndn::ptr_lib;
Yingdi Yu42f66462013-10-31 17:38:22 -070021
Yingdi Yueaa84e22014-01-16 10:30:26 -080022INIT_LOGGER("SecPolicyChronoChatPanel");
Yingdi Yu42f66462013-10-31 17:38:22 -070023
Yingdi Yueaa84e22014-01-16 10:30:26 -080024SecPolicyChronoChatPanel::SecPolicyChronoChatPanel(const int & stepLimit)
Yingdi Yu42f66462013-10-31 17:38:22 -070025 : m_stepLimit(stepLimit)
Yingdi Yu64206112013-12-24 11:16:32 +080026 , m_certificateCache()
Yingdi Yu42f66462013-10-31 17:38:22 -070027{
Yingdi Yu64206112013-12-24 11:16:32 +080028 m_localPrefixRegex = make_shared<Regex>("^<local><ndn><prefix><><>$");
Yingdi Yued8cfc42013-11-01 17:37:51 -070029
Yingdi Yueaa84e22014-01-16 10:30:26 -080030 m_invitationDataSigningRule = make_shared<SecRuleIdentity>("^<ndn><broadcast><chronos><invitation>([^<chatroom>]*)<chatroom>",
Yingdi Yu64206112013-12-24 11:16:32 +080031 "^([^<KEY>]*)<KEY>(<>*)<><ID-CERT><>$",
32 "==", "\\1", "\\1\\2", true);
Yingdi Yu42f66462013-10-31 17:38:22 -070033
Yingdi Yueaa84e22014-01-16 10:30:26 -080034 m_dskRule = make_shared<SecRuleIdentity>("^([^<KEY>]*)<KEY><dsk-.*><ID-CERT><>$",
Yingdi Yu64206112013-12-24 11:16:32 +080035 "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
36 "==", "\\1", "\\1\\2", true);
Yingdi Yu8dacdf22013-11-05 23:06:43 -080037
Yingdi Yueaa84e22014-01-16 10:30:26 -080038 m_endorseeRule = make_shared<SecRuleIdentity>("^([^<DNS>]*)<DNS><>*<ENDORSEE><>$",
Yingdi Yu64206112013-12-24 11:16:32 +080039 "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
40 "==", "\\1", "\\1\\2", true);
Yingdi Yu8dacdf22013-11-05 23:06:43 -080041
Yingdi Yu64206112013-12-24 11:16:32 +080042 m_kskRegex = make_shared<Regex>("^([^<KEY>]*)<KEY>(<>*<ksk-.*>)<ID-CERT><>$", "\\1\\2");
Yingdi Yu42f66462013-10-31 17:38:22 -070043
Yingdi Yu64206112013-12-24 11:16:32 +080044 m_keyNameRegex = make_shared<Regex>("^([^<KEY>]*)<KEY>(<>*<ksk-.*>)<ID-CERT>$", "\\1\\2");
Yingdi Yu42f66462013-10-31 17:38:22 -070045
Yingdi Yu64206112013-12-24 11:16:32 +080046 m_signingCertificateRegex = make_shared<Regex>("^<ndn><broadcast><chronos><invitation>([^<chatroom>]*)<chatroom>", "\\1");
Yingdi Yu42f66462013-10-31 17:38:22 -070047}
48
49bool
Yingdi Yueaa84e22014-01-16 10:30:26 -080050SecPolicyChronoChatPanel::skipVerifyAndTrust (const Data & data)
Yingdi Yu42f66462013-10-31 17:38:22 -070051{
52 if(m_localPrefixRegex->match(data.getName()))
53 return true;
54
55 return false;
56}
57
58bool
Yingdi Yueaa84e22014-01-16 10:30:26 -080059SecPolicyChronoChatPanel::requireVerify (const Data & data)
Yingdi Yu42f66462013-10-31 17:38:22 -070060{
61 // if(m_invitationDataRule->matchDataName(data))
62 // return true;
Yingdi Yued8cfc42013-11-01 17:37:51 -070063 if(m_kskRegex->match(data.getName()))
64 return true;
Yingdi Yu42f66462013-10-31 17:38:22 -070065 if(m_dskRule->matchDataName(data))
66 return true;
67
Yingdi Yu8dacdf22013-11-05 23:06:43 -080068 if(m_endorseeRule->matchDataName(data))
69 return true;
70
71
Yingdi Yu42f66462013-10-31 17:38:22 -070072 return false;
73}
74
Yingdi Yu64206112013-12-24 11:16:32 +080075shared_ptr<ValidationRequest>
Yingdi Yueaa84e22014-01-16 10:30:26 -080076SecPolicyChronoChatPanel::checkVerificationPolicy(const shared_ptr<Data>& data,
Yingdi Yu64206112013-12-24 11:16:32 +080077 int stepCount,
78 const OnVerified& onVerified,
79 const OnVerifyFailed& onVerifyFailed)
Yingdi Yu42f66462013-10-31 17:38:22 -070080{
Yingdi Yu42f66462013-10-31 17:38:22 -070081 if(m_stepLimit == stepCount)
82 {
Yingdi Yub35b8652013-11-07 11:32:40 -080083 _LOG_ERROR("Reach the maximum steps of verification!");
Yingdi Yu64206112013-12-24 11:16:32 +080084 onVerifyFailed(data);
Yingdi Yueaa84e22014-01-16 10:30:26 -080085 return shared_ptr<ValidationRequest>();
Yingdi Yu42f66462013-10-31 17:38:22 -070086 }
87
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -080088 try{
89 SignatureSha256WithRsa sig(data->getSignature());
90 const Name & keyLocatorName = sig.getKeyLocator().getName();
Yingdi Yu42f66462013-10-31 17:38:22 -070091
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -080092 if(m_kskRegex->match(data->getName()))
93 {
94 Name keyName = m_kskRegex->expand();
95 map<Name, PublicKey>::iterator it = m_trustAnchors.find(keyName);
96 if(m_trustAnchors.end() != it)
97 {
98 // _LOG_DEBUG("found key!");
99 IdentityCertificate identityCertificate(*data);
100 if(it->second == identityCertificate.getPublicKeyInfo())
101 onVerified(data);
102 else
103 onVerifyFailed(data);
104 }
105 else
106 onVerifyFailed(data);
Yingdi Yu42f66462013-10-31 17:38:22 -0700107
Yingdi Yueaa84e22014-01-16 10:30:26 -0800108 return shared_ptr<ValidationRequest>();
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800109 }
Yingdi Yu42f66462013-10-31 17:38:22 -0700110
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800111 if(m_dskRule->satisfy(*data))
112 {
113 m_keyNameRegex->match(keyLocatorName);
114 Name keyName = m_keyNameRegex->expand();
115
116 if(m_trustAnchors.end() != m_trustAnchors.find(keyName))
117 if(Verifier::verifySignature(*data, sig, m_trustAnchors[keyName]))
Yingdi Yu64206112013-12-24 11:16:32 +0800118 onVerified(data);
Yingdi Yued8cfc42013-11-01 17:37:51 -0700119 else
Yingdi Yu64206112013-12-24 11:16:32 +0800120 onVerifyFailed(data);
Yingdi Yu42f66462013-10-31 17:38:22 -0700121 else
Yingdi Yu64206112013-12-24 11:16:32 +0800122 onVerifyFailed(data);
Yingdi Yu42f66462013-10-31 17:38:22 -0700123
Yingdi Yueaa84e22014-01-16 10:30:26 -0800124 return shared_ptr<ValidationRequest>();
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800125 }
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800126
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800127 if(m_endorseeRule->satisfy(*data))
128 {
129 m_keyNameRegex->match(keyLocatorName);
130 Name keyName = m_keyNameRegex->expand();
131 if(m_trustAnchors.end() != m_trustAnchors.find(keyName))
132 if(Verifier::verifySignature(*data, sig, m_trustAnchors[keyName]))
133 onVerified(data);
134 else
135 onVerifyFailed(data);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800136 else
Yingdi Yu64206112013-12-24 11:16:32 +0800137 onVerifyFailed(data);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800138
Yingdi Yueaa84e22014-01-16 10:30:26 -0800139 return shared_ptr<ValidationRequest>();
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800140 }
141 }catch(SignatureSha256WithRsa::Error &e){
142 _LOG_DEBUG("checkVerificationPolicy: " << e.what());
143 onVerifyFailed(data);
Yingdi Yueaa84e22014-01-16 10:30:26 -0800144 return shared_ptr<ValidationRequest>();
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800145 }catch(KeyLocator::Error &e){
146 _LOG_DEBUG("checkVerificationPolicy: " << e.what());
147 onVerifyFailed(data);
Yingdi Yueaa84e22014-01-16 10:30:26 -0800148 return shared_ptr<ValidationRequest>();
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800149 }
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800150
Yingdi Yu42f66462013-10-31 17:38:22 -0700151 _LOG_DEBUG("Unverified!");
152
Yingdi Yu64206112013-12-24 11:16:32 +0800153 onVerifyFailed(data);
Yingdi Yueaa84e22014-01-16 10:30:26 -0800154 return shared_ptr<ValidationRequest>();
Yingdi Yu42f66462013-10-31 17:38:22 -0700155}
156
Yingdi Yu42f66462013-10-31 17:38:22 -0700157bool
Yingdi Yueaa84e22014-01-16 10:30:26 -0800158SecPolicyChronoChatPanel::checkSigningPolicy(const Name & dataName, const Name & certificateName)
Yingdi Yu42f66462013-10-31 17:38:22 -0700159{
160 return m_invitationDataSigningRule->satisfy(dataName, certificateName);
161}
162
163Name
Yingdi Yueaa84e22014-01-16 10:30:26 -0800164SecPolicyChronoChatPanel::inferSigningIdentity(const Name & dataName)
Yingdi Yu42f66462013-10-31 17:38:22 -0700165{
166 if(m_signingCertificateRegex->match(dataName))
167 return m_signingCertificateRegex->expand();
168 else
169 return Name();
170}
171
172void
Yingdi Yueaa84e22014-01-16 10:30:26 -0800173SecPolicyChronoChatPanel::addTrustAnchor(const EndorseCertificate& selfEndorseCertificate)
Yingdi Yu42f66462013-10-31 17:38:22 -0700174{
Yingdi Yuaccbda92013-12-27 08:44:12 +0800175 _LOG_DEBUG("Add Anchor: " << selfEndorseCertificate.getPublicKeyName().toUri());
Yingdi Yu64206112013-12-24 11:16:32 +0800176 m_trustAnchors.insert(pair <Name, PublicKey > (selfEndorseCertificate.getPublicKeyName(), selfEndorseCertificate.getPublicKeyInfo()));
Yingdi Yu42f66462013-10-31 17:38:22 -0700177}
Yingdi Yu6b56f092013-11-10 11:54:02 -0800178
Yingdi Yu6ea54e42013-11-12 17:50:21 -0800179void
Yingdi Yueaa84e22014-01-16 10:30:26 -0800180SecPolicyChronoChatPanel::removeTrustAnchor(const Name& keyName)
Yingdi Yu6ea54e42013-11-12 17:50:21 -0800181{
182 m_trustAnchors.erase(keyName);
183}
184
Yingdi Yu64206112013-12-24 11:16:32 +0800185shared_ptr<PublicKey>
Yingdi Yueaa84e22014-01-16 10:30:26 -0800186SecPolicyChronoChatPanel::getTrustedKey(const Name& inviterCertName)
Yingdi Yu6b56f092013-11-10 11:54:02 -0800187{
Yingdi Yu64206112013-12-24 11:16:32 +0800188 Name keyLocatorName = inviterCertName.getPrefix(-1);
Yingdi Yuaccbda92013-12-27 08:44:12 +0800189 _LOG_DEBUG("inviter cert name: " << inviterCertName.toUri());
Yingdi Yu6b56f092013-11-10 11:54:02 -0800190 m_keyNameRegex->match(keyLocatorName);
191 Name keyName = m_keyNameRegex->expand();
192
193 if(m_trustAnchors.end() != m_trustAnchors.find(keyName))
Yingdi Yu64206112013-12-24 11:16:32 +0800194 return make_shared<PublicKey>(m_trustAnchors[keyName]);
Yingdi Yueaa84e22014-01-16 10:30:26 -0800195 return shared_ptr<PublicKey>();
Yingdi Yu64206112013-12-24 11:16:32 +0800196}