blob: 9484196a8f23a176b3958ef5550d9e874dab65f2 [file] [log] [blame]
Zhiyi Zhangf5246c42017-01-26 09:39:20 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento914d05f2019-07-13 16:20:19 -04002/*
swa770de007bc2020-03-24 21:26:21 -07003 * Copyright (c) 2017-2020, Regents of the University of California.
Zhiyi Zhangf5246c42017-01-26 09:39:20 -08004 *
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 Zhangdbd9d432020-10-07 15:56:27 -070022#include "identity-challenge/challenge-module.hpp"
23#include "identity-challenge/challenge-email.hpp"
24#include "identity-challenge/challenge-pin.hpp"
Suyong Won7968f7a2020-05-12 01:01:25 -070025#include "protocol-detail/info.hpp"
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070026#include "requester.hpp"
Zhiyi Zhang5d80e1e2020-09-25 11:34:54 -070027#include "test-common.hpp"
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080028
29namespace ndn {
30namespace ndncert {
31namespace tests {
32
Zhiyi Zhangae123bf2017-04-14 12:24:53 -070033BOOST_FIXTURE_TEST_SUITE(TestCaModule, DatabaseFixture)
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080034
35BOOST_AUTO_TEST_CASE(Initialization)
36{
Zhiyi Zhang22998612020-09-25 14:43:23 -070037 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -070038 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
39 BOOST_CHECK_EQUAL(ca.getCaConf().m_caItem.m_caPrefix, "/ndn");
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080040
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080041 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070042 BOOST_CHECK_EQUAL(ca.m_registeredPrefixHandles.size(), 1); // removed local discovery registration
43 BOOST_CHECK_EQUAL(ca.m_interestFilterHandles.size(), 4); // onProbe, onNew, onChallenge, onRevoke
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080044}
45
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070046BOOST_AUTO_TEST_CASE(HandleProfileFetching)
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070047{
48 auto identity = addIdentity(Name("/ndn"));
49 auto key = identity.getDefaultKey();
50 auto cert = key.getDefaultCertificate();
51
Zhiyi Zhang22998612020-09-25 14:43:23 -070052 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -070053 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhangf61404d2020-10-07 15:41:07 -070054 auto metaData = ca.generateCaProfileMetaData();
55 auto profileData = ca.generateCaProfileData();
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070056 advanceClocks(time::milliseconds(20), 60);
57
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070058 Interest interest = MetadataObject::makeDiscoveryInterest(Name("/ndn/CA/INFO"));
59 shared_ptr<Interest> infoInterest = nullptr;
60
61 face.setInterestFilter(InterestFilter("/ndn/CA/INFO"),
62 [&](const auto&, const Interest& interest) {
63 if (interest.matchesData(*metaData)) {
64 face.put(*metaData);
65 }
66 else {
67 BOOST_CHECK(interest.matchesData(*profileData));
68 face.put(*profileData);
69 }
70 }, nullptr, nullptr);
71 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070072
73 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -070074 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070075 if (count == 0) {
76 count++;
77 auto block = response.getContent();
78 block.parse();
79 Interest interest(Name(block.get(tlv::Name)));
80 interest.setCanBePrefix(true);
81 infoInterest = make_shared<Interest>(interest);
82 }
83 else {
84 count++;
85 BOOST_CHECK(security::verifySignature(response, cert));
86 auto contentBlock = response.getContent();
87 contentBlock.parse();
88 auto caItem = INFO::decodeDataContent(contentBlock);
89 BOOST_CHECK_EQUAL(caItem.m_caPrefix, "/ndn");
90 BOOST_CHECK_EQUAL(caItem.m_probeParameterKeys.size(), 1);
91 BOOST_CHECK_EQUAL(caItem.m_probeParameterKeys.front(), "full name");
92 BOOST_CHECK_EQUAL(caItem.m_cert->wireEncode(), cert.wireEncode());
93 BOOST_CHECK_EQUAL(caItem.m_caInfo, "ndn testbed ca");
94 }
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -070095 });
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080096 face.receive(interest);
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080097 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070098 face.receive(*infoInterest);
99 advanceClocks(time::milliseconds(20), 60);
100 BOOST_CHECK_EQUAL(count, 2);
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800101}
102
Zhiyi Zhang6f395812020-09-29 14:42:03 -0700103BOOST_AUTO_TEST_CASE(HandleProbe)
104{
105 auto identity = addIdentity(Name("/ndn"));
106 auto key = identity.getDefaultKey();
107 auto cert = key.getDefaultCertificate();
108
109 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700110 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhang6f395812020-09-29 14:42:03 -0700111 advanceClocks(time::milliseconds(20), 60);
112
113 Interest interest("/ndn/CA/PROBE");
114 interest.setCanBePrefix(false);
115
116 Block paramTLV = makeEmptyBlock(tlv::ApplicationParameters);
117 paramTLV.push_back(makeStringBlock(tlv_parameter_key, "name"));
118 paramTLV.push_back(makeStringBlock(tlv_parameter_value, "zhiyi"));
119 paramTLV.encode();
120
121 interest.setApplicationParameters(paramTLV);
122
123 int count = 0;
124 face.onSendData.connect([&](const Data& response) {
125 count++;
126 BOOST_CHECK(security::verifySignature(response, cert));
127 Block contentBlock = response.getContent();
128 contentBlock.parse();
129 Block probeResponse = contentBlock.get(tlv_probe_response);
130 probeResponse.parse();
131 Name caName;
132 caName.wireDecode(probeResponse.get(tlv::Name));
Zhiyi Zhang8683ec92020-10-07 18:18:35 -0700133 BOOST_CHECK_EQUAL(caName.size(), 2);
Zhiyi Zhang6f395812020-09-29 14:42:03 -0700134 });
135 face.receive(interest);
136
137 advanceClocks(time::milliseconds(20), 60);
138 BOOST_CHECK_EQUAL(count, 1);
139}
140
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700141BOOST_AUTO_TEST_CASE(HandleProbeUsingDefaultHandler)
142{
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700143 auto identity = addIdentity(Name("/ndn"));
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700144 auto key = identity.getDefaultKey();
145 auto cert = key.getDefaultCertificate();
146
Zhiyi Zhang22998612020-09-25 14:43:23 -0700147 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700148 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700149 advanceClocks(time::milliseconds(20), 60);
150
swa770de007bc2020-03-24 21:26:21 -0700151 Interest interest("/ndn/CA/PROBE");
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700152 interest.setCanBePrefix(false);
Suyong Won7968f7a2020-05-12 01:01:25 -0700153
154 Block paramTLV = makeEmptyBlock(tlv::ApplicationParameters);
Zhiyi Zhang6f395812020-09-29 14:42:03 -0700155 paramTLV.push_back(makeStringBlock(tlv_parameter_key, "name"));
Suyong Won7968f7a2020-05-12 01:01:25 -0700156 paramTLV.push_back(makeStringBlock(tlv_parameter_value, "zhiyi"));
157 paramTLV.encode();
158
159 interest.setApplicationParameters(paramTLV);
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700160
161 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700162 face.onSendData.connect([&](const Data& response) {
163 count++;
164 BOOST_CHECK(security::verifySignature(response, cert));
165 auto contentBlock = response.getContent();
166 contentBlock.parse();
167 auto probeResponseBlock = contentBlock.get(tlv_probe_response);
168 probeResponseBlock.parse();
169 Name caPrefix;
170 caPrefix.wireDecode(probeResponseBlock.get(tlv::Name));
171 BOOST_CHECK(caPrefix != "");
172 });
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700173 face.receive(interest);
174
175 advanceClocks(time::milliseconds(20), 60);
176 BOOST_CHECK_EQUAL(count, 1);
177}
178
Suyong Wone2afeb52020-10-04 03:05:39 +0900179BOOST_AUTO_TEST_CASE(HandleProbeRedirection)
180{
181 auto identity = addIdentity(Name("/ndn"));
182 auto key = identity.getDefaultKey();
183 auto cert = key.getDefaultCertificate();
184
185 util::DummyClientFace face(io, m_keyChain, {true, true});
186 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-5", "ca-storage-memory");
Suyong Wone2afeb52020-10-04 03:05:39 +0900187 advanceClocks(time::milliseconds(20), 60);
188
189 Interest interest("/ndn/CA/PROBE");
190 interest.setCanBePrefix(false);
191
192 Block paramTLV = makeEmptyBlock(tlv::ApplicationParameters);
193 paramTLV.push_back(makeStringBlock(tlv_parameter_key, "name"));
194 paramTLV.push_back(makeStringBlock(tlv_parameter_value, "zhiyi"));
195 paramTLV.encode();
196
197 interest.setApplicationParameters(paramTLV);
198
199 int count = 0;
200 face.onSendData.connect([&](const Data& response) {
201 count++;
202 BOOST_CHECK(security::verifySignature(response, cert));
203 Block contentBlock = response.getContent();
204 contentBlock.parse();
205
206 // Test CA sent redirections
Zhiyi Zhang34a8d432020-10-03 22:14:25 -0700207 std::vector<Name> redirectionItems;
208 for (auto item : contentBlock.elements()) {
209 if (item.type() == tlv_probe_redirect) {
210 redirectionItems.push_back(Name(item.blockFromValue()));
211 }
Suyong Wone2afeb52020-10-04 03:05:39 +0900212 }
Zhiyi Zhang34a8d432020-10-03 22:14:25 -0700213 BOOST_CHECK_EQUAL(redirectionItems.size(), 2);
214 BOOST_CHECK_EQUAL(security::v2::extractIdentityFromCertName(redirectionItems[0].getPrefix(-1)), "/ndn/site1");
215 BOOST_CHECK_EQUAL(security::v2::extractIdentityFromCertName(redirectionItems[1].getPrefix(-1)), "/ndn/site1");
Suyong Wone2afeb52020-10-04 03:05:39 +0900216 });
217 face.receive(interest);
218 advanceClocks(time::milliseconds(20), 60);
219 BOOST_CHECK_EQUAL(count, 1);
220}
221
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800222BOOST_AUTO_TEST_CASE(HandleNew)
223{
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700224 auto identity = addIdentity(Name("/ndn"));
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800225 auto key = identity.getDefaultKey();
226 auto cert = key.getDefaultCertificate();
227
Zhiyi Zhang22998612020-09-25 14:43:23 -0700228 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700229 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800230 advanceClocks(time::milliseconds(20), 60);
231
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700232 CaProfile item;
Suyong Won256c9062020-05-11 02:45:56 -0700233 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700234 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700235 RequesterState state(m_keyChain, item, RequestType::NEW);
236 auto interest = Requester::genNewInterest(state, Name("/ndn/zhiyi"),
237 time::system_clock::now(),
238 time::system_clock::now() + time::days(1));
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800239
240 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700241 face.onSendData.connect([&](const Data& response) {
242 count++;
243 BOOST_CHECK(security::verifySignature(response, cert));
244 auto contentBlock = response.getContent();
245 contentBlock.parse();
Suyong Won7968f7a2020-05-12 01:01:25 -0700246
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700247 BOOST_CHECK(readString(contentBlock.get(tlv_ecdh_pub)) != "");
248 BOOST_CHECK(readString(contentBlock.get(tlv_salt)) != "");
249 BOOST_CHECK(readString(contentBlock.get(tlv_request_id)) != "");
Suyong Won7968f7a2020-05-12 01:01:25 -0700250
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700251 auto challengeBlockCount = 0;
252 for (auto const& element : contentBlock.elements()) {
253 if (element.type() == tlv_challenge) {
254 challengeBlockCount++;
Suyong Won7968f7a2020-05-12 01:01:25 -0700255 }
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700256 }
Suyong Won7968f7a2020-05-12 01:01:25 -0700257
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700258 BOOST_CHECK(challengeBlockCount != 0);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700259
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700260 auto challengeList = Requester::onNewRenewRevokeResponse(state, response);
tylerliu8e170d62020-09-30 01:31:53 -0700261 auto ca_encryption_key = ca.getCaStorage()->getRequest(readString(contentBlock.get(tlv_request_id))).m_encryptionKey;
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700262 BOOST_CHECK_EQUAL_COLLECTIONS(state.m_aesKey, state.m_aesKey + sizeof(state.m_aesKey),
tylerliu8e170d62020-09-30 01:31:53 -0700263 ca_encryption_key.value(), ca_encryption_key.value() + ca_encryption_key.value_size());
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700264 });
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700265 face.receive(*interest);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800266
267 advanceClocks(time::milliseconds(20), 60);
268 BOOST_CHECK_EQUAL(count, 1);
269}
270
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700271BOOST_AUTO_TEST_CASE(HandleNewWithInvalidValidityPeriod1)
272{
273 auto identity = addIdentity(Name("/ndn"));
274 auto key = identity.getDefaultKey();
275 auto cert = key.getDefaultCertificate();
276
Zhiyi Zhang22998612020-09-25 14:43:23 -0700277 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700278 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1");
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700279 advanceClocks(time::milliseconds(20), 60);
280
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700281 CaProfile item;
Suyong Won256c9062020-05-11 02:45:56 -0700282 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700283 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700284 RequesterState state(m_keyChain, item, RequestType::NEW);
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700285 auto current_tp = time::system_clock::now();
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700286 auto interest1 = Requester::genNewInterest(state, Name("/ndn/zhiyi"), current_tp, current_tp - time::hours(1));
287 auto interest2 = Requester::genNewInterest(state, Name("/ndn/zhiyi"), current_tp, current_tp + time::days(361));
288 auto interest3 = Requester::genNewInterest(state, Name("/ndn/zhiyi"), current_tp - time::hours(1), current_tp + time::hours(2));
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700289 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700290 auto contentTlv = response.getContent();
291 contentTlv.parse();
292 auto errorCode = static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv_error_code)));
293 BOOST_CHECK(errorCode != ErrorCode::NO_ERROR);
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700294 });
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700295 face.receive(*interest1);
296 face.receive(*interest2);
297 face.receive(*interest3);
298
299 advanceClocks(time::milliseconds(20), 60);
300}
301
tylerliu0b6d0db2020-09-28 17:52:02 -0700302BOOST_AUTO_TEST_CASE(HandleNewWithLongSuffix)
303{
304 auto identity = addIdentity(Name("/ndn"));
305 auto key = identity.getDefaultKey();
306 auto cert = key.getDefaultCertificate();
307
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700308 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700309 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
tylerliu0b6d0db2020-09-28 17:52:02 -0700310 advanceClocks(time::milliseconds(20), 60);
311
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700312 CaProfile item;
tylerliu0b6d0db2020-09-28 17:52:02 -0700313 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700314 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700315 RequesterState state(m_keyChain, item, RequestType::NEW);
tylerliu0b6d0db2020-09-28 17:52:02 -0700316
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700317 auto interest1 = Requester::genNewInterest(state, Name("/ndn/a"), time::system_clock::now(),
318 time::system_clock::now() + time::days(1));
319 auto interest2 = Requester::genNewInterest(state, Name("/ndn/a/b"), time::system_clock::now(),
320 time::system_clock::now() + time::days(1));
321 auto interest3 = Requester::genNewInterest(state, Name("/ndn/a/b/c/d"), time::system_clock::now(),
322 time::system_clock::now() + time::days(1));
tylerliu0b6d0db2020-09-28 17:52:02 -0700323
tylerliu0b6d0db2020-09-28 17:52:02 -0700324 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700325 auto contentTlv = response.getContent();
326 contentTlv.parse();
327 if (interest3->getName().isPrefixOf(response.getName())) {
328 auto errorCode = static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv_error_code)));
329 BOOST_CHECK(errorCode != ErrorCode::NO_ERROR);
330 }
331 else {
332 // should successfully get responses
333 BOOST_CHECK_EXCEPTION(readNonNegativeInteger(contentTlv.get(tlv_error_code)), std::runtime_error,
334 [](const auto& e) { return true; });
335 }
tylerliu0b6d0db2020-09-28 17:52:02 -0700336 });
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700337 face.receive(*interest1);
338 face.receive(*interest2);
339 face.receive(*interest3);
tylerliu0b6d0db2020-09-28 17:52:02 -0700340 advanceClocks(time::milliseconds(20), 60);
tylerliu0b6d0db2020-09-28 17:52:02 -0700341}
342
tylerliu0b6d0db2020-09-28 17:52:02 -0700343BOOST_AUTO_TEST_CASE(HandleNewWithInvalidLength1)
344{
345 auto identity = addIdentity(Name("/ndn"));
346 auto key = identity.getDefaultKey();
347 auto cert = key.getDefaultCertificate();
348
349 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700350 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1");
tylerliu0b6d0db2020-09-28 17:52:02 -0700351 advanceClocks(time::milliseconds(20), 60);
352
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700353 CaProfile item;
tylerliu0b6d0db2020-09-28 17:52:02 -0700354 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700355 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700356 RequesterState state(m_keyChain, item, RequestType::NEW);
357
tylerliu0b6d0db2020-09-28 17:52:02 -0700358 auto current_tp = time::system_clock::now();
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700359 auto interest1 = Requester::genNewInterest(state, Name("/ndn"), current_tp, current_tp + time::days(1));
360 auto interest2 = Requester::genNewInterest(state, Name("/ndn/a/b/c/d"), current_tp, current_tp + time::days(1));
tylerliu0b6d0db2020-09-28 17:52:02 -0700361 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700362 auto contentTlv = response.getContent();
363 contentTlv.parse();
364 auto errorCode = static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv_error_code)));
365 BOOST_CHECK(errorCode != ErrorCode::NO_ERROR);
tylerliu0b6d0db2020-09-28 17:52:02 -0700366 });
367 face.receive(*interest1);
368 face.receive(*interest2);
369
370 advanceClocks(time::milliseconds(20), 60);
371}
372
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700373BOOST_AUTO_TEST_CASE(HandleChallenge)
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800374{
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700375 auto identity = addIdentity(Name("/ndn"));
376 auto key = identity.getDefaultKey();
377 auto cert = key.getDefaultCertificate();
378
Zhiyi Zhang22998612020-09-25 14:43:23 -0700379 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700380 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800381 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700382
383 // generate NEW Interest
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700384 CaProfile item;
Suyong Won256c9062020-05-11 02:45:56 -0700385 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700386 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700387 RequesterState state(m_keyChain, item, RequestType::NEW);
388
389 auto newInterest = Requester::genNewInterest(state, Name("/ndn/zhiyi"), time::system_clock::now(),
390 time::system_clock::now() + time::days(1));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700391
392 // generate CHALLENGE Interest
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700393 shared_ptr<Interest> challengeInterest = nullptr;
394 shared_ptr<Interest> challengeInterest2 = nullptr;
395 shared_ptr<Interest> challengeInterest3 = nullptr;
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800396
397 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700398 face.onSendData.connect([&](const Data& response) {
swa770de007bc2020-03-24 21:26:21 -0700399 if (Name("/ndn/CA/NEW").isPrefixOf(response.getName())) {
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700400 auto challengeList = Requester::onNewRenewRevokeResponse(state, response);
401 auto paramList = Requester::selectOrContinueChallenge(state, "pin");
402 challengeInterest = Requester::genChallengeInterest(state, std::move(paramList));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700403 }
swa770de007bc2020-03-24 21:26:21 -0700404 else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 0) {
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800405 count++;
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700406 BOOST_CHECK(security::verifySignature(response, cert));
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800407
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700408 Requester::onChallengeResponse(state, response);
409 BOOST_CHECK(state.m_status == Status::CHALLENGE);
410 BOOST_CHECK_EQUAL(state.m_challengeStatus, ChallengePin::NEED_CODE);
411 auto paramList = Requester::selectOrContinueChallenge(state, "pin");
412 challengeInterest2 = Requester::genChallengeInterest(state, std::move(paramList));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700413 }
swa770de007bc2020-03-24 21:26:21 -0700414 else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 1) {
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700415 count++;
416 BOOST_CHECK(security::verifySignature(response, cert));
417
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700418 Requester::onChallengeResponse(state, response);
419 BOOST_CHECK(state.m_status == Status::CHALLENGE);
420 BOOST_CHECK_EQUAL(state.m_challengeStatus, ChallengePin::WRONG_CODE);
Davide Pesavento914d05f2019-07-13 16:20:19 -0400421
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700422 auto paramList = Requester::selectOrContinueChallenge(state, "pin");
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700423 auto request = ca.getCertificateRequest(*challengeInterest2);
Zhiyi Zhanga749f442020-09-29 17:19:51 -0700424 auto secret = request.m_challengeState->m_secrets.get(ChallengePin::PARAMETER_KEY_CODE, "");
Zhiyi Zhang46049832020-09-28 17:08:12 -0700425 std::get<1>(paramList[0]) = secret;
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700426 challengeInterest3 = Requester::genChallengeInterest(state, std::move(paramList));
427 std::cout << "CHALLENGE Interest Size: " << challengeInterest3->wireEncode().size() << std::endl;
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700428 }
swa770de007bc2020-03-24 21:26:21 -0700429 else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 2) {
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700430 count++;
431 BOOST_CHECK(security::verifySignature(response, cert));
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700432 Requester::onChallengeResponse(state, response);
433 BOOST_CHECK(state.m_status == Status::SUCCESS);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700434 }
Davide Pesavento914d05f2019-07-13 16:20:19 -0400435 });
436
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700437 face.receive(*newInterest);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800438 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700439 face.receive(*challengeInterest);
440 advanceClocks(time::milliseconds(20), 60);
441 face.receive(*challengeInterest2);
442 advanceClocks(time::milliseconds(20), 60);
443 face.receive(*challengeInterest3);
444 advanceClocks(time::milliseconds(20), 60);
445 BOOST_CHECK_EQUAL(count, 3);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800446}
447
tylerliu182bc532020-09-25 01:54:45 -0700448BOOST_AUTO_TEST_CASE(HandleRevoke)
449{
450 auto identity = addIdentity(Name("/ndn"));
451 auto key = identity.getDefaultKey();
452 auto cert = key.getDefaultCertificate();
453
Zhiyi Zhang46049832020-09-28 17:08:12 -0700454 util::DummyClientFace face(io, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700455 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
tylerliu182bc532020-09-25 01:54:45 -0700456 advanceClocks(time::milliseconds(20), 60);
457
458 //generate a certificate
459 auto clientIdentity = m_keyChain.createIdentity("/ndn/qwerty");
460 auto clientKey = clientIdentity.getDefaultKey();
461 security::v2::Certificate clientCert;
462 clientCert.setName(Name(clientKey.getName()).append("cert-request").appendVersion());
463 clientCert.setContentType(tlv::ContentType_Key);
464 clientCert.setFreshnessPeriod(time::hours(24));
465 clientCert.setContent(clientKey.getPublicKey().data(), clientKey.getPublicKey().size());
466 SignatureInfo signatureInfo;
467 signatureInfo.setValidityPeriod(security::ValidityPeriod(time::system_clock::now(),
Zhiyi Zhang46049832020-09-28 17:08:12 -0700468 time::system_clock::now() + time::hours(10)));
tylerliu182bc532020-09-25 01:54:45 -0700469 m_keyChain.sign(clientCert, signingByKey(clientKey.getName()).setSignatureInfo(signatureInfo));
tylerliu8704d032020-06-23 10:18:15 -0700470 CaState certRequest(Name("/ndn"), "122", RequestType::NEW, Status::SUCCESS, clientCert, makeEmptyBlock(tlv::ContentType_Key));
tylerliu182bc532020-09-25 01:54:45 -0700471 auto issuedCert = ca.issueCertificate(certRequest);
472
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700473 CaProfile item;
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700474 item.m_caPrefix = Name("/ndn");
475 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700476 RequesterState state(m_keyChain, item, RequestType::REVOKE);
tylerliu182bc532020-09-25 01:54:45 -0700477
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700478 auto interest = Requester::genRevokeInterest(state, issuedCert);
tylerliu182bc532020-09-25 01:54:45 -0700479
480 int count = 0;
Zhiyi Zhang46049832020-09-28 17:08:12 -0700481 face.onSendData.connect([&](const Data& response) {
tylerliu182bc532020-09-25 01:54:45 -0700482 count++;
483 BOOST_CHECK(security::verifySignature(response, cert));
484 auto contentBlock = response.getContent();
485 contentBlock.parse();
486
487 BOOST_CHECK(readString(contentBlock.get(tlv_ecdh_pub)) != "");
488 BOOST_CHECK(readString(contentBlock.get(tlv_salt)) != "");
489 BOOST_CHECK(readString(contentBlock.get(tlv_request_id)) != "");
490
491 auto challengeBlockCount = 0;
492 for (auto const& element : contentBlock.elements()) {
Zhiyi Zhang46049832020-09-28 17:08:12 -0700493 if (element.type() == tlv_challenge) {
494 challengeBlockCount++;
495 }
tylerliu182bc532020-09-25 01:54:45 -0700496 }
497
498 BOOST_CHECK(challengeBlockCount != 0);
499
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700500 auto challengeList = Requester::onNewRenewRevokeResponse(state, response);
tylerliu8e170d62020-09-30 01:31:53 -0700501 auto ca_encryption_key = ca.getCaStorage()->getRequest(readString(contentBlock.get(tlv_request_id))).m_encryptionKey;
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700502 BOOST_CHECK_EQUAL_COLLECTIONS(state.m_aesKey, state.m_aesKey + sizeof(state.m_aesKey),
tylerliu8e170d62020-09-30 01:31:53 -0700503 ca_encryption_key.value(), ca_encryption_key.value() + ca_encryption_key.value_size());
tylerliu182bc532020-09-25 01:54:45 -0700504 });
505 face.receive(*interest);
506
507 advanceClocks(time::milliseconds(20), 60);
508 BOOST_CHECK_EQUAL(count, 1);
509}
510
511BOOST_AUTO_TEST_CASE(HandleRevokeWithBadCert)
512{
513 auto identity = addIdentity(Name("/ndn"));
514 auto key = identity.getDefaultKey();
515 auto cert = key.getDefaultCertificate();
516
Zhiyi Zhang46049832020-09-28 17:08:12 -0700517 util::DummyClientFace face(io, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700518 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
tylerliu182bc532020-09-25 01:54:45 -0700519 advanceClocks(time::milliseconds(20), 60);
520
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700521 // generate a certificate
tylerliu182bc532020-09-25 01:54:45 -0700522 auto clientIdentity = m_keyChain.createIdentity("/ndn/qwerty");
523 auto clientKey = clientIdentity.getDefaultKey();
524 security::v2::Certificate clientCert;
525 clientCert.setName(Name(clientKey.getName()).append("NDNCERT").append(std::to_string(1473283247810732701)));
526 clientCert.setContentType(tlv::ContentType_Key);
527 clientCert.setFreshnessPeriod(time::hours(24));
528 clientCert.setContent(clientKey.getPublicKey().data(), clientKey.getPublicKey().size());
529 SignatureInfo signatureInfo;
530 signatureInfo.setValidityPeriod(security::ValidityPeriod(time::system_clock::now(),
Zhiyi Zhang46049832020-09-28 17:08:12 -0700531 time::system_clock::now() + time::hours(10)));
tylerliu182bc532020-09-25 01:54:45 -0700532 m_keyChain.sign(clientCert, signingByKey(clientKey.getName()).setSignatureInfo(signatureInfo));
533
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700534 CaProfile item;
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700535 item.m_caPrefix = Name("/ndn");
536 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700537 RequesterState state(m_keyChain, item, RequestType::NEW);
tylerliu182bc532020-09-25 01:54:45 -0700538
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700539 auto interest = Requester::genRevokeInterest(state, clientCert);
tylerliu182bc532020-09-25 01:54:45 -0700540
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700541 bool receiveData = false;
Zhiyi Zhang46049832020-09-28 17:08:12 -0700542 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700543 receiveData = true;
544 auto contentTlv = response.getContent();
545 contentTlv.parse();
546 BOOST_CHECK(static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv_error_code))) != ErrorCode::NO_ERROR);
tylerliu182bc532020-09-25 01:54:45 -0700547 });
548 face.receive(*interest);
549
550 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700551 BOOST_CHECK_EQUAL(receiveData, true);
tylerliu182bc532020-09-25 01:54:45 -0700552}
553
Zhiyi Zhang46049832020-09-28 17:08:12 -0700554BOOST_AUTO_TEST_SUITE_END() // TestCaModule
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800555
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700556} // namespace tests
557} // namespace ndncert
558} // namespace ndn