blob: 67a1f33862e89bba56ae784acfa8785ce2b262ca [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
118Verifier::verifySignature(const Data& data, const SignatureSha256WithRsa& sig, const PublicKey& key)
119{
120 using namespace CryptoPP;
121
122 bool result = false;
123
124 RSA::PublicKey publicKey;
125 ByteQueue queue;
126
127 queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
128 publicKey.Load(queue);
129
130 RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
131 result = verifier.VerifyMessage(data.wireEncode().value(), data.wireEncode().value_size() - data.getSignature().getValue().size(),
132 sig.getValue().value(), sig.getValue().value_size());
133
134 _LOG_DEBUG("Signature verified? " << data.getName().toUri() << " " << boolalpha << result);
135
136 return result;
137}
138
139}