blob: a2ba790e0cb29842645097a353ea26a38ed8299b [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
21#include <ndn-cpp/security/verifier.hpp>
22
23#include <ndn-cpp/security/policy/policy-manager.hpp>
24
25#include <cryptopp/rsa.h>
26
27#include "../util/logging.hpp"
28
29using namespace std;
30using namespace ndn::func_lib;
31#if NDN_CPP_HAVE_CXX11
32// In the std library, the placeholders are in a different namespace than boost.
33using namespace ndn::func_lib::placeholders;
34#endif
35
36INIT_LOGGER("ndn.Verifier");
37
38namespace ndn {
39const ptr_lib::shared_ptr<PolicyManager> Verifier::DefaultPolicyManager = ptr_lib::shared_ptr<PolicyManager>();
40
41Verifier::Verifier(const ptr_lib::shared_ptr<PolicyManager> &policyManager /* = DefaultPolicyManager */)
42 : policyManager_(policyManager)
43{
44 if (policyManager_ == DefaultPolicyManager)
45 {
46 // #ifdef USE_SIMPLE_POLICY_MANAGER
47 // Ptr<SimplePolicyManager> policyManager = Ptr<SimplePolicyManager>(new SimplePolicyManager());
48 // Ptr<IdentityPolicyRule> rule1 = Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>",
49 // "^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>",
50 // ">", "\\1\\2", "\\1", true));
51 // Ptr<IdentityPolicyRule> rule2 = Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>",
52 // "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>",
53 // "==", "\\1", "\\1\\2", true));
54 // Ptr<IdentityPolicyRule> rule3 = Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^(<>*)$",
55 // "^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>",
56 // ">", "\\1", "\\1", true));
57 // policyManager->addVerificationPolicyRule(rule1);
58 // policyManager->addVerificationPolicyRule(rule2);
59 // policyManager->addVerificationPolicyRule(rule3);
60
61 // policyManager->addSigningPolicyRule(rule3);
62
63 // m_policyManager = policyManager;
64 //
65 // #else
66 // policyManager_ = new NoVerifyPolicyManager();
67 // #endif
68 }
69}
70
71void
72Verifier::verifyData
73 (const ptr_lib::shared_ptr<Data>& data, const OnVerified& onVerified, const OnVerifyFailed& onVerifyFailed, int stepCount)
74{
75 if (policies().requireVerify(*data)) {
76 ptr_lib::shared_ptr<ValidationRequest> nextStep = policyManager_->checkVerificationPolicy
77 (data, stepCount, onVerified, onVerifyFailed);
78 if (static_cast<bool>(nextStep))
79 {
80 if (!face_)
81 throw Error("Face should be set prior to verifyData method to call");
82
83 face_->expressInterest
84 (*nextStep->interest_,
85 bind(&Verifier::onCertificateData, this, _1, _2, nextStep),
86 bind(&Verifier::onCertificateInterestTimeout, this, _1, nextStep->retry_, onVerifyFailed, data, nextStep));
87 }
88 }
89 else if (policies().skipVerifyAndTrust(*data))
90 onVerified(data);
91 else
92 onVerifyFailed(data);
93}
94
95void
96Verifier::onCertificateData(const ptr_lib::shared_ptr<const Interest> &interest, const ptr_lib::shared_ptr<Data> &data, ptr_lib::shared_ptr<ValidationRequest> nextStep)
97{
98 // Try to verify the certificate (data) according to the parameters in nextStep.
99 verifyData(data, nextStep->onVerified_, nextStep->onVerifyFailed_, nextStep->stepCount_);
100}
101
102void
103Verifier::onCertificateInterestTimeout
104 (const ptr_lib::shared_ptr<const Interest> &interest, int retry, const OnVerifyFailed& onVerifyFailed, const ptr_lib::shared_ptr<Data> &data,
105 ptr_lib::shared_ptr<ValidationRequest> nextStep)
106{
107 if (retry > 0)
108 // Issue the same expressInterest as in verifyData except decrement retry.
109 face_->expressInterest
110 (*interest,
111 bind(&Verifier::onCertificateData, this, _1, _2, nextStep),
112 bind(&Verifier::onCertificateInterestTimeout, this, _1, retry - 1, onVerifyFailed, data, nextStep));
113 else
114 onVerifyFailed(data);
115}
116
117bool
Yingdi Yu913b0c72014-01-10 18:02:55 -0800118Verifier::verifySignature(const Data& data, const Signature& sig, const PublicKey& key)
119{
120 try{
121 switch(sig.getType()){
122 case Signature::Sha256WithRsa:
123 {
124 SignatureSha256WithRsa sigSha256Rsa(sig);
125 return verifySignature(data, sigSha256Rsa, key);
126 }
127 default:
128 {
129 _LOG_DEBUG("verifySignature: Unknown signature type: " << sig.getType());
130 return false;
131 }
132 }
133 }catch(Signature::Error &e){
134 _LOG_DEBUG("verifySignature: " << e.what());
135 return false;
136 }
137 return false;
138}
139
140bool
141Verifier::verifySignature(const Buffer &data, const Signature &sig, const PublicKey &key)
142{
143 try{
144 switch(sig.getType()){
145 case Signature::Sha256WithRsa:
146 {
147 SignatureSha256WithRsa sigSha256Rsa(sig);
148 return verifySignature(data, sigSha256Rsa, key);
149 }
150 default:
151 {
152 _LOG_DEBUG("verifySignature: Unknown signature type: " << sig.getType());
153 return false;
154 }
155 }
156 }catch(Signature::Error &e){
157 _LOG_DEBUG("verifySignature: " << e.what());
158 return false;
159 }
160 return false;
161}
162
163bool
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800164Verifier::verifySignature(const Data& data, const SignatureSha256WithRsa& sig, const PublicKey& key)
165{
166 using namespace CryptoPP;
167
168 bool result = false;
169
170 RSA::PublicKey publicKey;
171 ByteQueue queue;
172
173 queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
174 publicKey.Load(queue);
175
176 RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
177 result = verifier.VerifyMessage(data.wireEncode().value(), data.wireEncode().value_size() - data.getSignature().getValue().size(),
178 sig.getValue().value(), sig.getValue().value_size());
179
180 _LOG_DEBUG("Signature verified? " << data.getName().toUri() << " " << boolalpha << result);
181
182 return result;
183}
184
Yingdi Yu913b0c72014-01-10 18:02:55 -0800185bool
186Verifier::verifySignature(const Buffer& data, const SignatureSha256WithRsa& sig, const PublicKey& key)
187{
188 using namespace CryptoPP;
189
190 bool result = false;
191
192 RSA::PublicKey publicKey;
193 ByteQueue queue;
194
195 queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
196 publicKey.Load(queue);
197
198 RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
199 result = verifier.VerifyMessage(data.buf(), data.size(),
200 sig.getValue().value(), sig.getValue().value_size());
201
202 _LOG_DEBUG("Signature verified? " << data.getName().toUri() << " " << boolalpha << result);
203
204 return result;
205}
206
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800207}