blob: cef89979eba34a6b566ceb279ceb88a85cf8419b [file] [log] [blame]
Yingdi Yu2abd73f2014-01-08 23:34:11 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
3 * Copyright (C) 2013 Regents of the University of California.
4 * @author: Yingdi Yu <yingdi@cs.ucla.edu>
5 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
6 * See COPYING for copyright and distribution information.
7 */
8
9#if __clang__
10#pragma clang diagnostic push
11#pragma clang diagnostic ignored "-Wreorder"
12#pragma clang diagnostic ignored "-Wtautological-compare"
13#pragma clang diagnostic ignored "-Wunused-variable"
14#pragma clang diagnostic ignored "-Wunused-function"
15#elif __GNUC__
16#pragma GCC diagnostic ignored "-Wreorder"
17#pragma GCC diagnostic ignored "-Wunused-variable"
18#pragma GCC diagnostic ignored "-Wunused-function"
19#endif
20
Alexander Afanasyev09c613f2014-01-29 00:23:58 -080021#include "security/verifier.hpp"
Yingdi Yu2abd73f2014-01-08 23:34:11 -080022
Alexander Afanasyev09c613f2014-01-29 00:23:58 -080023#include "security/sec-policy.hpp"
Yingdi Yu2abd73f2014-01-08 23:34:11 -080024
25#include <cryptopp/rsa.h>
26
27#include "../util/logging.hpp"
28
29using namespace std;
Yingdi Yu2abd73f2014-01-08 23:34:11 -080030#if NDN_CPP_HAVE_CXX11
31// In the std library, the placeholders are in a different namespace than boost.
32using namespace ndn::func_lib::placeholders;
33#endif
34
35INIT_LOGGER("ndn.Verifier");
36
37namespace ndn {
Yingdi Yu4f324632014-01-15 18:10:03 -080038const ptr_lib::shared_ptr<SecPolicy> Verifier::DefaultPolicy = ptr_lib::shared_ptr<SecPolicy>();
Yingdi Yu2abd73f2014-01-08 23:34:11 -080039
Yingdi Yu4f324632014-01-15 18:10:03 -080040Verifier::Verifier(const ptr_lib::shared_ptr<SecPolicy> &policy /* = DefaultPolicy */)
Yingdi Yue07e3392014-01-28 10:29:27 -080041 : m_policy(policy)
Yingdi Yu2abd73f2014-01-08 23:34:11 -080042{
Yingdi Yue07e3392014-01-28 10:29:27 -080043 if (m_policy == DefaultPolicy)
Yingdi Yu2abd73f2014-01-08 23:34:11 -080044 {
45 // #ifdef USE_SIMPLE_POLICY_MANAGER
46 // Ptr<SimplePolicyManager> policyManager = Ptr<SimplePolicyManager>(new SimplePolicyManager());
47 // Ptr<IdentityPolicyRule> rule1 = Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>",
48 // "^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>",
49 // ">", "\\1\\2", "\\1", true));
50 // Ptr<IdentityPolicyRule> rule2 = Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>",
51 // "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>",
52 // "==", "\\1", "\\1\\2", true));
53 // Ptr<IdentityPolicyRule> rule3 = Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^(<>*)$",
54 // "^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>",
55 // ">", "\\1", "\\1", true));
56 // policyManager->addVerificationPolicyRule(rule1);
57 // policyManager->addVerificationPolicyRule(rule2);
58 // policyManager->addVerificationPolicyRule(rule3);
59
60 // policyManager->addSigningPolicyRule(rule3);
61
62 // m_policyManager = policyManager;
63 //
64 // #else
Yingdi Yu4f324632014-01-15 18:10:03 -080065 // policy_ = new NoVerifyPolicyManager();
Yingdi Yu2abd73f2014-01-08 23:34:11 -080066 // #endif
67 }
68}
69
70void
Yingdi Yue07e3392014-01-28 10:29:27 -080071Verifier::verify(const ptr_lib::shared_ptr<const Interest> &interest,
72 const OnVerified &onVerified,
73 const OnVerifyFailed &onVerifyFailed,
74 int stepCount)
Yingdi Yu2abd73f2014-01-08 23:34:11 -080075{
Yingdi Yue07e3392014-01-28 10:29:27 -080076 //It does not make sense to verify Interest without specified policy, verification must fail!
77 if(!static_cast<bool>(m_policy))
78 onVerifyFailed();
Yingdi Yu2abd73f2014-01-08 23:34:11 -080079 else
Yingdi Yue07e3392014-01-28 10:29:27 -080080 {
81 //check verification policy
82 ptr_lib::shared_ptr<ValidationRequest> nextStep = m_policy->checkVerificationPolicy(interest, stepCount, onVerified, onVerifyFailed);
83 if (static_cast<bool>(nextStep))
84 {
85 if(!m_face)
86 throw Error("Face should be set prior to verify method to call");
87
88 m_face->expressInterest
89 (*nextStep->m_interest,
90 func_lib::bind(&Verifier::onCertificateData, this, _1, _2, nextStep),
91 func_lib::bind(&Verifier::onCertificateInterestTimeout, this, _1, nextStep->m_retry, onVerifyFailed, nextStep));
92 }
93 else
94 {
95 //If there is no nextStep, that means InterestPolicy has already been able to verify the Interest.
96 //No more further processes.
97 }
98 }
Yingdi Yu2abd73f2014-01-08 23:34:11 -080099}
100
101void
Yingdi Yue07e3392014-01-28 10:29:27 -0800102Verifier::verify(const ptr_lib::shared_ptr<const Data> &data,
103 const OnVerified &onVerified,
104 const OnVerifyFailed &onVerifyFailed,
105 int stepCount)
106{
107 //It does not make sense to verify Interest without specified policy, verification must fail!
108 if(!static_cast<bool>(m_policy))
109 onVerifyFailed();
110 else
111 {
112 //check verification policy
113 ptr_lib::shared_ptr<ValidationRequest> nextStep = m_policy->checkVerificationPolicy(data, stepCount, onVerified, onVerifyFailed);
114 if (static_cast<bool>(nextStep))
115 {
116 if(!m_face)
117 throw Error("Face should be set prior to verify method to call");
118
119 m_face->expressInterest
120 (*nextStep->m_interest,
121 func_lib::bind(&Verifier::onCertificateData, this, _1, _2, nextStep),
122 func_lib::bind(&Verifier::onCertificateInterestTimeout, this, _1, nextStep->m_retry, onVerifyFailed, nextStep));
123 }
124 else
125 {
126 //If there is no nextStep, that means InterestPolicy has already been able to verify the Interest.
127 //No more further processes.
128 }
129 }
130}
131
132void
133Verifier::onCertificateData(const ptr_lib::shared_ptr<const Interest> &interest,
134 const ptr_lib::shared_ptr<Data> &data,
135 ptr_lib::shared_ptr<ValidationRequest> nextStep)
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800136{
137 // Try to verify the certificate (data) according to the parameters in nextStep.
Yingdi Yue07e3392014-01-28 10:29:27 -0800138 verify(data,
139 func_lib::bind(nextStep->m_onVerified, data),
140 func_lib::bind(nextStep->m_onVerifyFailed, data),
141 nextStep->m_stepCount);
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800142}
143
144void
145Verifier::onCertificateInterestTimeout
Yingdi Yue07e3392014-01-28 10:29:27 -0800146 (const ptr_lib::shared_ptr<const Interest> &interest, int retry, const OnVerifyFailed& onVerifyFailed, ptr_lib::shared_ptr<ValidationRequest> nextStep)
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800147{
148 if (retry > 0)
149 // Issue the same expressInterest as in verifyData except decrement retry.
Yingdi Yue07e3392014-01-28 10:29:27 -0800150 m_face->expressInterest
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800151 (*interest,
Yingdi Yue07e3392014-01-28 10:29:27 -0800152 func_lib::bind(&Verifier::onCertificateData, this, _1, _2, nextStep),
153 func_lib::bind(&Verifier::onCertificateInterestTimeout, this, _1, retry - 1, onVerifyFailed, nextStep));
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800154 else
Yingdi Yue07e3392014-01-28 10:29:27 -0800155 onVerifyFailed();
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800156}
157
158bool
Yingdi Yu913b0c72014-01-10 18:02:55 -0800159Verifier::verifySignature(const Data& data, const Signature& sig, const PublicKey& key)
160{
161 try{
162 switch(sig.getType()){
163 case Signature::Sha256WithRsa:
164 {
165 SignatureSha256WithRsa sigSha256Rsa(sig);
166 return verifySignature(data, sigSha256Rsa, key);
167 }
168 default:
169 {
170 _LOG_DEBUG("verifySignature: Unknown signature type: " << sig.getType());
171 return false;
172 }
173 }
174 }catch(Signature::Error &e){
175 _LOG_DEBUG("verifySignature: " << e.what());
176 return false;
177 }
178 return false;
179}
180
181bool
182Verifier::verifySignature(const Buffer &data, const Signature &sig, const PublicKey &key)
183{
184 try{
185 switch(sig.getType()){
186 case Signature::Sha256WithRsa:
187 {
188 SignatureSha256WithRsa sigSha256Rsa(sig);
189 return verifySignature(data, sigSha256Rsa, key);
190 }
191 default:
192 {
193 _LOG_DEBUG("verifySignature: Unknown signature type: " << sig.getType());
194 return false;
195 }
196 }
197 }catch(Signature::Error &e){
198 _LOG_DEBUG("verifySignature: " << e.what());
199 return false;
200 }
201 return false;
202}
203
204bool
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800205Verifier::verifySignature(const Data& data, const SignatureSha256WithRsa& sig, const PublicKey& key)
206{
207 using namespace CryptoPP;
208
209 bool result = false;
210
211 RSA::PublicKey publicKey;
212 ByteQueue queue;
213
214 queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
215 publicKey.Load(queue);
216
217 RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
218 result = verifier.VerifyMessage(data.wireEncode().value(), data.wireEncode().value_size() - data.getSignature().getValue().size(),
219 sig.getValue().value(), sig.getValue().value_size());
220
221 _LOG_DEBUG("Signature verified? " << data.getName().toUri() << " " << boolalpha << result);
222
223 return result;
224}
225
Yingdi Yu913b0c72014-01-10 18:02:55 -0800226bool
227Verifier::verifySignature(const Buffer& data, const SignatureSha256WithRsa& sig, const PublicKey& key)
228{
229 using namespace CryptoPP;
230
231 bool result = false;
232
233 RSA::PublicKey publicKey;
234 ByteQueue queue;
235
236 queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
237 publicKey.Load(queue);
238
239 RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
240 result = verifier.VerifyMessage(data.buf(), data.size(),
241 sig.getValue().value(), sig.getValue().value_size());
242
243 _LOG_DEBUG("Signature verified? " << data.getName().toUri() << " " << boolalpha << result);
244
245 return result;
246}
247
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800248}