blob: 5d23a9f36f9f214e074ca932e7f9237bcd88dfd9 [file] [log] [blame]
Zhiyi Zhangf5246c42017-01-26 09:39:20 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2017, Regents of the University of California.
4 *
5 * This file is part of ndncert, a certificate management system based on NDN.
6 *
7 * ndncert is free software: you can redistribute it and/or modify it under the terms
8 * of the GNU General Public License as published by the Free Software Foundation, either
9 * version 3 of the License, or (at your option) any later version.
10 *
11 * ndncert is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License along with
16 * ndncert, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * See AUTHORS.md for complete list of ndncert authors and contributors.
19 */
20
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080021#include "ca-module.hpp"
Zhiyi Zhangad6cf932017-10-26 16:19:15 -070022
23#include "database-fixture.hpp"
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080024#include "client-module.hpp"
25#include "challenge-module.hpp"
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +080026
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080027#include <ndn-cxx/util/dummy-client-face.hpp>
28#include <ndn-cxx/security/signing-helpers.hpp>
29#include <ndn-cxx/security/transform/public-key.hpp>
30#include <ndn-cxx/security/verification-helpers.hpp>
31
32namespace ndn {
33namespace ndncert {
34namespace tests {
35
Zhiyi Zhangae123bf2017-04-14 12:24:53 -070036BOOST_FIXTURE_TEST_SUITE(TestCaModule, DatabaseFixture)
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080037
38BOOST_AUTO_TEST_CASE(Initialization)
39{
40 util::DummyClientFace face(m_io, {true, true});
41 CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test");
Zhiyi Zhangad6cf932017-10-26 16:19:15 -070042 BOOST_CHECK_EQUAL(ca.getCaConf().m_caItems.front().m_caName.toUri(), "/ndn");
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080043 BOOST_CHECK_EQUAL(ca.getCaConf().m_caItems.back().m_caName.toUri(), "/ndn/site1");
44
45 auto identity = addIdentity(Name("/ndn/site2"));
46 auto key = identity.getDefaultKey();
47 auto cert = key.getDefaultCertificate();
48 ca.getCaStorage()->addCertificate("111", cert);
49 BOOST_CHECK_EQUAL(ca.getCaStorage()->getCertificate("111").getIdentity(), Name("/ndn/site2"));
50
51 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +080052 BOOST_CHECK_EQUAL(ca.m_registeredPrefixIds.size(), 4);
53 BOOST_CHECK_EQUAL(ca.m_interestFilterIds.size(), 18);
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080054}
55
56BOOST_AUTO_TEST_CASE(HandleProbe)
57{
58 auto identity = addIdentity(Name("/ndn/site1"));
59 auto key = identity.getDefaultKey();
60 auto cert = key.getDefaultCertificate();
61
62 util::DummyClientFace face(m_io, {true, true});
63 CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test");
Zhiyi Zhang7420cf52017-12-18 18:59:21 +080064 ca.setProbeHandler(Name("/ndn/site1"), [&] (const std::string& probeInfo) {
65 return probeInfo + "example";
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080066 });
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080067
68 advanceClocks(time::milliseconds(20), 60);
69
70 Name interestName("/ndn/site1/CA");
71 interestName.append("_PROBE").append("zhiyi");
72 Interest interest(interestName);
73
74 int count = 0;
75 face.onSendData.connect([&] (const Data& response) {
76 count++;
77 BOOST_CHECK(security::verifySignature(response, cert));
78 JsonSection contentJson = ClientModule::getJsonFromData(response);
Zhiyi Zhang7420cf52017-12-18 18:59:21 +080079 BOOST_CHECK_EQUAL(contentJson.get(JSON_IDNENTIFIER, ""), "/ndn/site1/zhiyiexample");
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080080 });
81 face.receive(interest);
82
83 advanceClocks(time::milliseconds(20), 60);
84 BOOST_CHECK_EQUAL(count, 1);
85}
86
Zhiyi Zhanga63b7372017-05-17 14:14:34 -070087BOOST_AUTO_TEST_CASE(HandleProbeUsingDefaultHandler)
88{
89 auto identity = addIdentity(Name("/ndn/site1"));
90 auto key = identity.getDefaultKey();
91 auto cert = key.getDefaultCertificate();
92
93 util::DummyClientFace face(m_io, {true, true});
94 CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test");
Zhiyi Zhanga63b7372017-05-17 14:14:34 -070095
96 advanceClocks(time::milliseconds(20), 60);
97
98 Name interestName("/ndn/site1/CA");
99 interestName.append("_PROBE").append("zhiyi");
100 Interest interest(interestName);
101
102 int count = 0;
103 face.onSendData.connect([&] (const Data& response) {
104 count++;
105 BOOST_CHECK(security::verifySignature(response, cert));
106 JsonSection contentJson = ClientModule::getJsonFromData(response);
107 BOOST_CHECK_EQUAL(contentJson.get(JSON_IDNENTIFIER, ""), "/ndn/site1/zhiyi");
108 });
109 face.receive(interest);
110
111 advanceClocks(time::milliseconds(20), 60);
112 BOOST_CHECK_EQUAL(count, 1);
113}
114
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800115BOOST_AUTO_TEST_CASE(HandleNew)
116{
117 auto identity = addIdentity(Name("/ndn/site1"));
118 auto key = identity.getDefaultKey();
119 auto cert = key.getDefaultCertificate();
120
121 util::DummyClientFace face(m_io, {true, true});
122 util::DummyClientFace face2(m_io, {true, true});
123
124 CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test");
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800125 advanceClocks(time::milliseconds(20), 60);
126
127 Name identityName("/ndn/site1");
128 identityName.append("zhiyi");
129 ClientModule client(face2, m_keyChain);
130 ClientCaItem item;
131 item.m_caName = Name("/ndn/site1/CA");
132 item.m_anchor = cert;
133 client.getClientConf().m_caItems.push_back(item);
134
135 int nClientInterest = 0;
136 int nCaData = 0;
137 int nClientCallback = 0;
138
139 face.onSendData.connect([&] (const Data& data) {
140 nCaData++;
141 JsonSection contentJson = ClientModule::getJsonFromData(data);
142 BOOST_CHECK(!contentJson.get(JSON_REQUEST_ID, "").empty());
143 face2.receive(data);
144 });
145 face2.onSendInterest.connect([&] (const Interest& interest) {
146 nClientInterest++;
147 face.receive(interest);
148 });
149
150 client.sendNew(item, identityName,
151 [&] (const shared_ptr<RequestState> state) {
152 nClientCallback++;
153 BOOST_CHECK(state->m_requestId != "");
154 },
155 [] (const std::string& s) { BOOST_CHECK(false); });
156
157 advanceClocks(time::milliseconds(20), 60);
158
159 BOOST_CHECK_EQUAL(nClientCallback, 1);
160 BOOST_CHECK_EQUAL(nCaData, 1);
161 BOOST_CHECK_EQUAL(nClientInterest, 1);
162}
163
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800164BOOST_AUTO_TEST_CASE(HandleLocalhostList)
165{
166 auto identity0 = addIdentity(Name("/ndn"));
167 auto identity1 = addIdentity(Name("/ndn/edu/ucla/cs/zhiyi"));
168 auto identity2 = addIdentity(Name("/ndn/site1"));
169 m_keyChain.setDefaultIdentity(identity0);
170
171 util::DummyClientFace face(m_io, {true, true});
172 CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test");
173
174 advanceClocks(time::milliseconds(20), 60);
175 Interest interest(Name("/localhost/CA/_LIST"));
176
177 int count = 0;
178 face.onSendData.connect([&] (const Data& response) {
179 count++;
180 JsonSection contentJson = ClientModule::getJsonFromData(response);
181 ClientConfig clientConf;
182 clientConf.load(contentJson);
183 BOOST_CHECK_EQUAL(clientConf.m_caItems.size(), 3);
184 });
185 face.receive(interest);
186
187 advanceClocks(time::milliseconds(20), 60);
188 BOOST_CHECK_EQUAL(count, 1);
189}
190
191BOOST_AUTO_TEST_CASE(HandleList)
192{
193 auto identity0 = addIdentity(Name("/ndn"));
194 util::DummyClientFace face(m_io, {true, true});
195 CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test");
196
197 advanceClocks(time::milliseconds(20), 60);
198 Interest interest(Name("/ndn/CA/_LIST"));
199
200 int count = 0;
201 face.onSendData.connect([&] (const Data& response) {
202 count++;
203 JsonSection contentJson = ClientModule::getJsonFromData(response);
204 BOOST_CHECK_EQUAL(contentJson.get_child("ca-list").size(), 2);
205 std::string schemaDataName = contentJson.get<std::string>("trust-schema");
206 BOOST_CHECK_EQUAL(schemaDataName, "TODO: add trust schema");
207 });
208 face.receive(interest);
209
210 advanceClocks(time::milliseconds(20), 60);
211 BOOST_CHECK_EQUAL(count, 1);
212}
213
214BOOST_AUTO_TEST_CASE(HandleTargetList)
215{
216 auto identity0 = addIdentity(Name("/ndn"));
217 util::DummyClientFace face(m_io, {true, true});
218 CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test");
219 ca.setRecommendCaHandler(Name("/ndn"),
220 [] (const std::string& input, const std::list<Name>& list) -> std::tuple<Name, std::string> {
221 Name recommendedCa;
222 std::string identity;
223 for (auto caName : list) {
224 std::string univName = readString(caName.get(-1));
225 if (input.find(univName) != std::string::npos) {
226 recommendedCa = caName;
227 identity = input.substr(0, input.find("@"));
228 }
229 }
230 return std::make_tuple(recommendedCa, identity);
231 });
232
233 advanceClocks(time::milliseconds(20), 60);
234 Interest interest(Name("/ndn/CA/_LIST/example@memphis.edu"));
235
236 int count = 0;
237 face.onSendData.connect([&] (const Data& response) {
238 count++;
239 JsonSection contentJson = ClientModule::getJsonFromData(response);
240 std::string recommendedCA = contentJson.get<std::string>("recommended-ca");
241 std::string recommendedIdentity = contentJson.get<std::string>("recommended-identity");
242 std::string schemaDataName = contentJson.get<std::string>("trust-schema");
243 BOOST_CHECK_EQUAL(recommendedCA, "/ndn/edu/memphis");
244 BOOST_CHECK_EQUAL(recommendedIdentity, "example");
245 BOOST_CHECK_EQUAL(schemaDataName, "TODO: add trust schema");
246 });
247 face.receive(interest);
248
249 advanceClocks(time::milliseconds(20), 60);
250 BOOST_CHECK_EQUAL(count, 1);
251}
252
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800253BOOST_AUTO_TEST_SUITE_END() // TestCaModule
254
255} // namespace tests
256} // namespace ndncert
257} // namespace ndn