blob: 3c87c46c6f2e909242360bc99387a0899cb4fe16 [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"
12#include "logging.h"
13
14using namespace std;
15using namespace ndn;
16using namespace ndn::security;
17
18INIT_LOGGER("InvitationPolicyManager");
19
20InvitationPolicyManager::InvitationPolicyManager(const int & stepLimit,
21 Ptr<CertificateCache> certificateCache,
22 Name signingIdentity)
23 : m_stepLimit(stepLimit)
24 , m_certificateCache(certificateCache)
25 , m_localPrefixRegex(Ptr<Regex>(new Regex("^<local><ndn><prefix><><>$")))
26{
27 m_invitationDataRule = Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^<ndn><broadcast><chronos><invitation>([^<chatroom>]*)<chatroom>",
28 "^([^<KEY>]*)<KEY><DSK-.*><ID-CERT>$",
29 "==", "\\1", "\\1", true));
30
31 m_dskRule = Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^([^<KEY>]*)<KEY><DSK-.*><ID-CERT>$",
32 "^([^<KEY>]*)<KEY>(<>*)<KSK-.*><ID-CERT>$",
33 "==", "\\1", "\\1\\2", true));
34 m_signingCertificateRegex = Ptr<Regex>(new Regex("^<ndn><broadcast><chronos><invitation>([^<chatroom>]*)<chatroom>", "\\1"));
35}
36
37bool
38InvitationPolicyManager::skipVerifyAndTrust (const Data & data)
39{
40 if(m_localPrefixRegex->match(data.getName()))
41 return true;
42
43 return false;
44}
45
46bool
47InvitationPolicyManager::requireVerify (const Data & data)
48{
49 if(m_invitationDataRule->matchDataName(data))
50 return true;
51
52 if(m_dskRule->matchDataName(data))
53 return true;
54
55 return false;
56}
57
58Ptr<ValidationRequest>
59InvitationPolicyManager::checkVerificationPolicy(Ptr<Data> data,
60 const int & stepCount,
61 const DataCallback& verifiedCallback,
62 const UnverifiedCallback& unverifiedCallback)
63{
64 if(m_stepLimit == stepCount)
65 {
66 _LOG_DEBUG("reach the maximum steps of verification");
67 unverifiedCallback(data);
68 return NULL;
69 }
70
71 Ptr<const signature::Sha256WithRsa> sha256sig = boost::dynamic_pointer_cast<const signature::Sha256WithRsa> (data->getSignature());
72
73 if(KeyLocator::KEYNAME != sha256sig->getKeyLocator().getType())
74 {
75 unverifiedCallback(data);
76 return NULL;
77 }
78
79 const Name & keyLocatorName = sha256sig->getKeyLocator().getKeyName();
80
81 if(m_invitationDataRule->satisfy(*data))
82 {
83 Ptr<const IdentityCertificate> trustedCert = m_certificateCache->getCertificate(keyLocatorName);
84
85 if(NULL != trustedCert){
86 if(verifySignature(*data, trustedCert->getPublicKeyInfo()))
87 verifiedCallback(data);
88 else
89 unverifiedCallback(data);
90
91 return NULL;
92 }
93 else{
94 _LOG_DEBUG("KeyLocator has not been cached and validated!");
95
96 DataCallback recursiveVerifiedCallback = boost::bind(&InvitationPolicyManager::onCertificateVerified,
97 this,
98 _1,
99 data,
100 verifiedCallback,
101 unverifiedCallback);
102
103 UnverifiedCallback recursiveUnverifiedCallback = boost::bind(&InvitationPolicyManager::onCertificateUnverified,
104 this,
105 _1,
106 data,
107 unverifiedCallback);
108
109
110 Ptr<Interest> interest = Ptr<Interest>(new Interest(sha256sig->getKeyLocator().getKeyName()));
111
112 Ptr<ValidationRequest> nextStep = Ptr<ValidationRequest>(new ValidationRequest(interest,
113 recursiveVerifiedCallback,
114 recursiveUnverifiedCallback,
115 0,
116 stepCount + 1)
117 );
118 return nextStep;
119 }
120 }
121
122 if(m_dskRule->satisfy(*data))
123 {
124 Ptr<IdentityCertificate> trustedCert;
125 if(m_trustAnchors.end() != m_trustAnchors.find(keyLocatorName))
126 trustedCert = m_trustAnchors[keyLocatorName];
127 else
128 {
129 unverifiedCallback(data);
130 return NULL;
131 }
132
133 if(verifySignature(*data, trustedCert->getPublicKeyInfo()))
134 verifiedCallback(data);
135 else
136 unverifiedCallback(data);
137
138 return NULL;
139 }
140}
141
142void
143InvitationPolicyManager::onCertificateVerified(Ptr<Data> certData,
144 Ptr<Data> originalData,
145 const DataCallback& verifiedCallback,
146 const UnverifiedCallback& unverifiedCallback)
147{
148 IdentityCertificate certificate(*certData);
149
150 if(verifySignature(*originalData, certificate.getPublicKeyInfo()))
151 verifiedCallback(originalData);
152 else
153 unverifiedCallback(originalData);
154
155 return NULL;
156}
157
158void
159InvitationPolicyManager::onCertificateUnverified(Ptr<Data> certData,
160 Ptr<Data> originalData,
161 const UnverifiedCallback& unverifiedCallback)
162{ unverifiedCallback(originalData); }
163
164bool
165InvitationPolicyManager::checkSigningPolicy(const Name & dataName, const Name & certificateName)
166{
167 return m_invitationDataRule->satisfy(dataName, certificateName);
168}
169
170Name
171InvitationPolicyManager::inferSigningIdentity(const Name & dataName)
172{
173 if(m_signingCertificateRegex->match(data))
174 return m_signingCertificateRegex->expand();
175 else
176 return Name();
177}
178
179void
180InvitationPolicyManager::addTrustAnchor(Ptr<IdentityCertificate> ksk)
181{
182 Name name = ksk->getName();
183 m_cache.insert(pair <Name, Ptr<IdentityCertificate> > (name, ksk));
184}