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