blob: a7b98756d48727fd29fc0530fb1f7a31a36664c7 [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
Zhiyi Zhang696cd042020-10-07 21:27:36 -070043 BOOST_CHECK_EQUAL(ca.m_interestFilterHandles.size(), 5); // infoMeta, 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 Zhang696cd042020-10-07 21:27:36 -070054 auto profileData = ca.getCaProfileData();
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070055 advanceClocks(time::milliseconds(20), 60);
56
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070057 Interest interest = MetadataObject::makeDiscoveryInterest(Name("/ndn/CA/INFO"));
58 shared_ptr<Interest> infoInterest = nullptr;
59
Zhiyi Zhang696cd042020-10-07 21:27:36 -070060 face.setInterestFilter(
61 InterestFilter("/ndn/CA/INFO"),
62 [&](const auto&, const Interest& interest) {
63 BOOST_CHECK(interest.matchesData(profileData));
64 face.put(profileData);
65 }, nullptr, nullptr);
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070066 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070067
68 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -070069 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070070 if (count == 0) {
71 count++;
72 auto block = response.getContent();
73 block.parse();
74 Interest interest(Name(block.get(tlv::Name)));
75 interest.setCanBePrefix(true);
76 infoInterest = make_shared<Interest>(interest);
77 }
78 else {
79 count++;
80 BOOST_CHECK(security::verifySignature(response, cert));
81 auto contentBlock = response.getContent();
82 contentBlock.parse();
83 auto caItem = INFO::decodeDataContent(contentBlock);
84 BOOST_CHECK_EQUAL(caItem.m_caPrefix, "/ndn");
85 BOOST_CHECK_EQUAL(caItem.m_probeParameterKeys.size(), 1);
86 BOOST_CHECK_EQUAL(caItem.m_probeParameterKeys.front(), "full name");
87 BOOST_CHECK_EQUAL(caItem.m_cert->wireEncode(), cert.wireEncode());
88 BOOST_CHECK_EQUAL(caItem.m_caInfo, "ndn testbed ca");
89 }
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -070090 });
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080091 face.receive(interest);
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080092 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070093 face.receive(*infoInterest);
94 advanceClocks(time::milliseconds(20), 60);
95 BOOST_CHECK_EQUAL(count, 2);
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080096}
97
Zhiyi Zhang6f395812020-09-29 14:42:03 -070098BOOST_AUTO_TEST_CASE(HandleProbe)
99{
100 auto identity = addIdentity(Name("/ndn"));
101 auto key = identity.getDefaultKey();
102 auto cert = key.getDefaultCertificate();
103
104 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700105 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhang6f395812020-09-29 14:42:03 -0700106 advanceClocks(time::milliseconds(20), 60);
107
108 Interest interest("/ndn/CA/PROBE");
109 interest.setCanBePrefix(false);
110
111 Block paramTLV = makeEmptyBlock(tlv::ApplicationParameters);
112 paramTLV.push_back(makeStringBlock(tlv_parameter_key, "name"));
113 paramTLV.push_back(makeStringBlock(tlv_parameter_value, "zhiyi"));
114 paramTLV.encode();
115
116 interest.setApplicationParameters(paramTLV);
117
118 int count = 0;
119 face.onSendData.connect([&](const Data& response) {
120 count++;
121 BOOST_CHECK(security::verifySignature(response, cert));
122 Block contentBlock = response.getContent();
123 contentBlock.parse();
124 Block probeResponse = contentBlock.get(tlv_probe_response);
125 probeResponse.parse();
126 Name caName;
127 caName.wireDecode(probeResponse.get(tlv::Name));
Zhiyi Zhang8683ec92020-10-07 18:18:35 -0700128 BOOST_CHECK_EQUAL(caName.size(), 2);
Zhiyi Zhang6f395812020-09-29 14:42:03 -0700129 });
130 face.receive(interest);
131
132 advanceClocks(time::milliseconds(20), 60);
133 BOOST_CHECK_EQUAL(count, 1);
134}
135
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700136BOOST_AUTO_TEST_CASE(HandleProbeUsingDefaultHandler)
137{
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700138 auto identity = addIdentity(Name("/ndn"));
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700139 auto key = identity.getDefaultKey();
140 auto cert = key.getDefaultCertificate();
141
Zhiyi Zhang22998612020-09-25 14:43:23 -0700142 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700143 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700144 advanceClocks(time::milliseconds(20), 60);
145
swa770de007bc2020-03-24 21:26:21 -0700146 Interest interest("/ndn/CA/PROBE");
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700147 interest.setCanBePrefix(false);
Suyong Won7968f7a2020-05-12 01:01:25 -0700148
149 Block paramTLV = makeEmptyBlock(tlv::ApplicationParameters);
Zhiyi Zhang6f395812020-09-29 14:42:03 -0700150 paramTLV.push_back(makeStringBlock(tlv_parameter_key, "name"));
Suyong Won7968f7a2020-05-12 01:01:25 -0700151 paramTLV.push_back(makeStringBlock(tlv_parameter_value, "zhiyi"));
152 paramTLV.encode();
153
154 interest.setApplicationParameters(paramTLV);
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700155
156 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700157 face.onSendData.connect([&](const Data& response) {
158 count++;
159 BOOST_CHECK(security::verifySignature(response, cert));
160 auto contentBlock = response.getContent();
161 contentBlock.parse();
162 auto probeResponseBlock = contentBlock.get(tlv_probe_response);
163 probeResponseBlock.parse();
164 Name caPrefix;
165 caPrefix.wireDecode(probeResponseBlock.get(tlv::Name));
166 BOOST_CHECK(caPrefix != "");
167 });
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700168 face.receive(interest);
169
170 advanceClocks(time::milliseconds(20), 60);
171 BOOST_CHECK_EQUAL(count, 1);
172}
173
Suyong Wone2afeb52020-10-04 03:05:39 +0900174BOOST_AUTO_TEST_CASE(HandleProbeRedirection)
175{
176 auto identity = addIdentity(Name("/ndn"));
177 auto key = identity.getDefaultKey();
178 auto cert = key.getDefaultCertificate();
179
180 util::DummyClientFace face(io, m_keyChain, {true, true});
181 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-5", "ca-storage-memory");
Suyong Wone2afeb52020-10-04 03:05:39 +0900182 advanceClocks(time::milliseconds(20), 60);
183
184 Interest interest("/ndn/CA/PROBE");
185 interest.setCanBePrefix(false);
186
187 Block paramTLV = makeEmptyBlock(tlv::ApplicationParameters);
188 paramTLV.push_back(makeStringBlock(tlv_parameter_key, "name"));
189 paramTLV.push_back(makeStringBlock(tlv_parameter_value, "zhiyi"));
190 paramTLV.encode();
191
192 interest.setApplicationParameters(paramTLV);
193
194 int count = 0;
195 face.onSendData.connect([&](const Data& response) {
196 count++;
197 BOOST_CHECK(security::verifySignature(response, cert));
198 Block contentBlock = response.getContent();
199 contentBlock.parse();
200
201 // Test CA sent redirections
Zhiyi Zhang34a8d432020-10-03 22:14:25 -0700202 std::vector<Name> redirectionItems;
203 for (auto item : contentBlock.elements()) {
204 if (item.type() == tlv_probe_redirect) {
205 redirectionItems.push_back(Name(item.blockFromValue()));
206 }
Suyong Wone2afeb52020-10-04 03:05:39 +0900207 }
Zhiyi Zhang34a8d432020-10-03 22:14:25 -0700208 BOOST_CHECK_EQUAL(redirectionItems.size(), 2);
209 BOOST_CHECK_EQUAL(security::v2::extractIdentityFromCertName(redirectionItems[0].getPrefix(-1)), "/ndn/site1");
210 BOOST_CHECK_EQUAL(security::v2::extractIdentityFromCertName(redirectionItems[1].getPrefix(-1)), "/ndn/site1");
Suyong Wone2afeb52020-10-04 03:05:39 +0900211 });
212 face.receive(interest);
213 advanceClocks(time::milliseconds(20), 60);
214 BOOST_CHECK_EQUAL(count, 1);
215}
216
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800217BOOST_AUTO_TEST_CASE(HandleNew)
218{
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700219 auto identity = addIdentity(Name("/ndn"));
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800220 auto key = identity.getDefaultKey();
221 auto cert = key.getDefaultCertificate();
222
Zhiyi Zhang22998612020-09-25 14:43:23 -0700223 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700224 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800225 advanceClocks(time::milliseconds(20), 60);
226
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700227 CaProfile item;
Suyong Won256c9062020-05-11 02:45:56 -0700228 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700229 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700230 RequesterState state(m_keyChain, item, RequestType::NEW);
231 auto interest = Requester::genNewInterest(state, Name("/ndn/zhiyi"),
232 time::system_clock::now(),
233 time::system_clock::now() + time::days(1));
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800234
235 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700236 face.onSendData.connect([&](const Data& response) {
237 count++;
238 BOOST_CHECK(security::verifySignature(response, cert));
239 auto contentBlock = response.getContent();
240 contentBlock.parse();
Suyong Won7968f7a2020-05-12 01:01:25 -0700241
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700242 BOOST_CHECK(readString(contentBlock.get(tlv_ecdh_pub)) != "");
243 BOOST_CHECK(readString(contentBlock.get(tlv_salt)) != "");
244 BOOST_CHECK(readString(contentBlock.get(tlv_request_id)) != "");
Suyong Won7968f7a2020-05-12 01:01:25 -0700245
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700246 auto challengeBlockCount = 0;
247 for (auto const& element : contentBlock.elements()) {
248 if (element.type() == tlv_challenge) {
249 challengeBlockCount++;
Suyong Won7968f7a2020-05-12 01:01:25 -0700250 }
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700251 }
Suyong Won7968f7a2020-05-12 01:01:25 -0700252
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700253 BOOST_CHECK(challengeBlockCount != 0);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700254
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700255 auto challengeList = Requester::onNewRenewRevokeResponse(state, response);
tylerliu8e170d62020-09-30 01:31:53 -0700256 auto ca_encryption_key = ca.getCaStorage()->getRequest(readString(contentBlock.get(tlv_request_id))).m_encryptionKey;
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700257 BOOST_CHECK_EQUAL_COLLECTIONS(state.m_aesKey, state.m_aesKey + sizeof(state.m_aesKey),
tylerliu8e170d62020-09-30 01:31:53 -0700258 ca_encryption_key.value(), ca_encryption_key.value() + ca_encryption_key.value_size());
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700259 });
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700260 face.receive(*interest);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800261
262 advanceClocks(time::milliseconds(20), 60);
263 BOOST_CHECK_EQUAL(count, 1);
264}
265
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700266BOOST_AUTO_TEST_CASE(HandleNewWithInvalidValidityPeriod1)
267{
268 auto identity = addIdentity(Name("/ndn"));
269 auto key = identity.getDefaultKey();
270 auto cert = key.getDefaultCertificate();
271
Zhiyi Zhang22998612020-09-25 14:43:23 -0700272 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700273 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1");
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700274 advanceClocks(time::milliseconds(20), 60);
275
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700276 CaProfile item;
Suyong Won256c9062020-05-11 02:45:56 -0700277 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700278 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700279 RequesterState state(m_keyChain, item, RequestType::NEW);
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700280 auto current_tp = time::system_clock::now();
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700281 auto interest1 = Requester::genNewInterest(state, Name("/ndn/zhiyi"), current_tp, current_tp - time::hours(1));
282 auto interest2 = Requester::genNewInterest(state, Name("/ndn/zhiyi"), current_tp, current_tp + time::days(361));
283 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 -0700284 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700285 auto contentTlv = response.getContent();
286 contentTlv.parse();
287 auto errorCode = static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv_error_code)));
288 BOOST_CHECK(errorCode != ErrorCode::NO_ERROR);
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700289 });
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700290 face.receive(*interest1);
291 face.receive(*interest2);
292 face.receive(*interest3);
293
294 advanceClocks(time::milliseconds(20), 60);
295}
296
tylerliu0b6d0db2020-09-28 17:52:02 -0700297BOOST_AUTO_TEST_CASE(HandleNewWithLongSuffix)
298{
299 auto identity = addIdentity(Name("/ndn"));
300 auto key = identity.getDefaultKey();
301 auto cert = key.getDefaultCertificate();
302
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700303 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700304 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
tylerliu0b6d0db2020-09-28 17:52:02 -0700305 advanceClocks(time::milliseconds(20), 60);
306
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700307 CaProfile item;
tylerliu0b6d0db2020-09-28 17:52:02 -0700308 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700309 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700310 RequesterState state(m_keyChain, item, RequestType::NEW);
tylerliu0b6d0db2020-09-28 17:52:02 -0700311
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700312 auto interest1 = Requester::genNewInterest(state, Name("/ndn/a"), time::system_clock::now(),
313 time::system_clock::now() + time::days(1));
314 auto interest2 = Requester::genNewInterest(state, Name("/ndn/a/b"), time::system_clock::now(),
315 time::system_clock::now() + time::days(1));
316 auto interest3 = Requester::genNewInterest(state, Name("/ndn/a/b/c/d"), time::system_clock::now(),
317 time::system_clock::now() + time::days(1));
tylerliu0b6d0db2020-09-28 17:52:02 -0700318
tylerliu0b6d0db2020-09-28 17:52:02 -0700319 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700320 auto contentTlv = response.getContent();
321 contentTlv.parse();
322 if (interest3->getName().isPrefixOf(response.getName())) {
323 auto errorCode = static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv_error_code)));
324 BOOST_CHECK(errorCode != ErrorCode::NO_ERROR);
325 }
326 else {
327 // should successfully get responses
328 BOOST_CHECK_EXCEPTION(readNonNegativeInteger(contentTlv.get(tlv_error_code)), std::runtime_error,
329 [](const auto& e) { return true; });
330 }
tylerliu0b6d0db2020-09-28 17:52:02 -0700331 });
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700332 face.receive(*interest1);
333 face.receive(*interest2);
334 face.receive(*interest3);
tylerliu0b6d0db2020-09-28 17:52:02 -0700335 advanceClocks(time::milliseconds(20), 60);
tylerliu0b6d0db2020-09-28 17:52:02 -0700336}
337
tylerliu0b6d0db2020-09-28 17:52:02 -0700338BOOST_AUTO_TEST_CASE(HandleNewWithInvalidLength1)
339{
340 auto identity = addIdentity(Name("/ndn"));
341 auto key = identity.getDefaultKey();
342 auto cert = key.getDefaultCertificate();
343
344 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700345 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1");
tylerliu0b6d0db2020-09-28 17:52:02 -0700346 advanceClocks(time::milliseconds(20), 60);
347
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700348 CaProfile item;
tylerliu0b6d0db2020-09-28 17:52:02 -0700349 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700350 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700351 RequesterState state(m_keyChain, item, RequestType::NEW);
352
tylerliu0b6d0db2020-09-28 17:52:02 -0700353 auto current_tp = time::system_clock::now();
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700354 auto interest1 = Requester::genNewInterest(state, Name("/ndn"), current_tp, current_tp + time::days(1));
355 auto interest2 = Requester::genNewInterest(state, Name("/ndn/a/b/c/d"), current_tp, current_tp + time::days(1));
tylerliu0b6d0db2020-09-28 17:52:02 -0700356 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700357 auto contentTlv = response.getContent();
358 contentTlv.parse();
359 auto errorCode = static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv_error_code)));
360 BOOST_CHECK(errorCode != ErrorCode::NO_ERROR);
tylerliu0b6d0db2020-09-28 17:52:02 -0700361 });
362 face.receive(*interest1);
363 face.receive(*interest2);
364
365 advanceClocks(time::milliseconds(20), 60);
366}
367
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700368BOOST_AUTO_TEST_CASE(HandleChallenge)
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800369{
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700370 auto identity = addIdentity(Name("/ndn"));
371 auto key = identity.getDefaultKey();
372 auto cert = key.getDefaultCertificate();
373
Zhiyi Zhang22998612020-09-25 14:43:23 -0700374 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700375 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800376 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700377
378 // generate NEW Interest
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700379 CaProfile item;
Suyong Won256c9062020-05-11 02:45:56 -0700380 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700381 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700382 RequesterState state(m_keyChain, item, RequestType::NEW);
383
384 auto newInterest = Requester::genNewInterest(state, Name("/ndn/zhiyi"), time::system_clock::now(),
385 time::system_clock::now() + time::days(1));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700386
387 // generate CHALLENGE Interest
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700388 shared_ptr<Interest> challengeInterest = nullptr;
389 shared_ptr<Interest> challengeInterest2 = nullptr;
390 shared_ptr<Interest> challengeInterest3 = nullptr;
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800391
392 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700393 face.onSendData.connect([&](const Data& response) {
swa770de007bc2020-03-24 21:26:21 -0700394 if (Name("/ndn/CA/NEW").isPrefixOf(response.getName())) {
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700395 auto challengeList = Requester::onNewRenewRevokeResponse(state, response);
396 auto paramList = Requester::selectOrContinueChallenge(state, "pin");
397 challengeInterest = Requester::genChallengeInterest(state, std::move(paramList));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700398 }
swa770de007bc2020-03-24 21:26:21 -0700399 else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 0) {
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800400 count++;
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700401 BOOST_CHECK(security::verifySignature(response, cert));
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800402
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700403 Requester::onChallengeResponse(state, response);
404 BOOST_CHECK(state.m_status == Status::CHALLENGE);
405 BOOST_CHECK_EQUAL(state.m_challengeStatus, ChallengePin::NEED_CODE);
406 auto paramList = Requester::selectOrContinueChallenge(state, "pin");
407 challengeInterest2 = Requester::genChallengeInterest(state, std::move(paramList));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700408 }
swa770de007bc2020-03-24 21:26:21 -0700409 else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 1) {
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700410 count++;
411 BOOST_CHECK(security::verifySignature(response, cert));
412
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700413 Requester::onChallengeResponse(state, response);
414 BOOST_CHECK(state.m_status == Status::CHALLENGE);
415 BOOST_CHECK_EQUAL(state.m_challengeStatus, ChallengePin::WRONG_CODE);
Davide Pesavento914d05f2019-07-13 16:20:19 -0400416
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700417 auto paramList = Requester::selectOrContinueChallenge(state, "pin");
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700418 auto request = ca.getCertificateRequest(*challengeInterest2);
Zhiyi Zhanga749f442020-09-29 17:19:51 -0700419 auto secret = request.m_challengeState->m_secrets.get(ChallengePin::PARAMETER_KEY_CODE, "");
Zhiyi Zhang46049832020-09-28 17:08:12 -0700420 std::get<1>(paramList[0]) = secret;
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700421 challengeInterest3 = Requester::genChallengeInterest(state, std::move(paramList));
422 std::cout << "CHALLENGE Interest Size: " << challengeInterest3->wireEncode().size() << std::endl;
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700423 }
swa770de007bc2020-03-24 21:26:21 -0700424 else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 2) {
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700425 count++;
426 BOOST_CHECK(security::verifySignature(response, cert));
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700427 Requester::onChallengeResponse(state, response);
428 BOOST_CHECK(state.m_status == Status::SUCCESS);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700429 }
Davide Pesavento914d05f2019-07-13 16:20:19 -0400430 });
431
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700432 face.receive(*newInterest);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800433 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700434 face.receive(*challengeInterest);
435 advanceClocks(time::milliseconds(20), 60);
436 face.receive(*challengeInterest2);
437 advanceClocks(time::milliseconds(20), 60);
438 face.receive(*challengeInterest3);
439 advanceClocks(time::milliseconds(20), 60);
440 BOOST_CHECK_EQUAL(count, 3);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800441}
442
tylerliu182bc532020-09-25 01:54:45 -0700443BOOST_AUTO_TEST_CASE(HandleRevoke)
444{
445 auto identity = addIdentity(Name("/ndn"));
446 auto key = identity.getDefaultKey();
447 auto cert = key.getDefaultCertificate();
448
Zhiyi Zhang46049832020-09-28 17:08:12 -0700449 util::DummyClientFace face(io, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700450 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
tylerliu182bc532020-09-25 01:54:45 -0700451 advanceClocks(time::milliseconds(20), 60);
452
453 //generate a certificate
454 auto clientIdentity = m_keyChain.createIdentity("/ndn/qwerty");
455 auto clientKey = clientIdentity.getDefaultKey();
456 security::v2::Certificate clientCert;
457 clientCert.setName(Name(clientKey.getName()).append("cert-request").appendVersion());
458 clientCert.setContentType(tlv::ContentType_Key);
459 clientCert.setFreshnessPeriod(time::hours(24));
460 clientCert.setContent(clientKey.getPublicKey().data(), clientKey.getPublicKey().size());
461 SignatureInfo signatureInfo;
462 signatureInfo.setValidityPeriod(security::ValidityPeriod(time::system_clock::now(),
Zhiyi Zhang46049832020-09-28 17:08:12 -0700463 time::system_clock::now() + time::hours(10)));
tylerliu182bc532020-09-25 01:54:45 -0700464 m_keyChain.sign(clientCert, signingByKey(clientKey.getName()).setSignatureInfo(signatureInfo));
tylerliu8704d032020-06-23 10:18:15 -0700465 CaState certRequest(Name("/ndn"), "122", RequestType::NEW, Status::SUCCESS, clientCert, makeEmptyBlock(tlv::ContentType_Key));
tylerliu182bc532020-09-25 01:54:45 -0700466 auto issuedCert = ca.issueCertificate(certRequest);
467
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700468 CaProfile item;
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700469 item.m_caPrefix = Name("/ndn");
470 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700471 RequesterState state(m_keyChain, item, RequestType::REVOKE);
tylerliu182bc532020-09-25 01:54:45 -0700472
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700473 auto interest = Requester::genRevokeInterest(state, issuedCert);
tylerliu182bc532020-09-25 01:54:45 -0700474
475 int count = 0;
Zhiyi Zhang46049832020-09-28 17:08:12 -0700476 face.onSendData.connect([&](const Data& response) {
tylerliu182bc532020-09-25 01:54:45 -0700477 count++;
478 BOOST_CHECK(security::verifySignature(response, cert));
479 auto contentBlock = response.getContent();
480 contentBlock.parse();
481
482 BOOST_CHECK(readString(contentBlock.get(tlv_ecdh_pub)) != "");
483 BOOST_CHECK(readString(contentBlock.get(tlv_salt)) != "");
484 BOOST_CHECK(readString(contentBlock.get(tlv_request_id)) != "");
485
486 auto challengeBlockCount = 0;
487 for (auto const& element : contentBlock.elements()) {
Zhiyi Zhang46049832020-09-28 17:08:12 -0700488 if (element.type() == tlv_challenge) {
489 challengeBlockCount++;
490 }
tylerliu182bc532020-09-25 01:54:45 -0700491 }
492
493 BOOST_CHECK(challengeBlockCount != 0);
494
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700495 auto challengeList = Requester::onNewRenewRevokeResponse(state, response);
tylerliu8e170d62020-09-30 01:31:53 -0700496 auto ca_encryption_key = ca.getCaStorage()->getRequest(readString(contentBlock.get(tlv_request_id))).m_encryptionKey;
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700497 BOOST_CHECK_EQUAL_COLLECTIONS(state.m_aesKey, state.m_aesKey + sizeof(state.m_aesKey),
tylerliu8e170d62020-09-30 01:31:53 -0700498 ca_encryption_key.value(), ca_encryption_key.value() + ca_encryption_key.value_size());
tylerliu182bc532020-09-25 01:54:45 -0700499 });
500 face.receive(*interest);
501
502 advanceClocks(time::milliseconds(20), 60);
503 BOOST_CHECK_EQUAL(count, 1);
504}
505
506BOOST_AUTO_TEST_CASE(HandleRevokeWithBadCert)
507{
508 auto identity = addIdentity(Name("/ndn"));
509 auto key = identity.getDefaultKey();
510 auto cert = key.getDefaultCertificate();
511
Zhiyi Zhang46049832020-09-28 17:08:12 -0700512 util::DummyClientFace face(io, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700513 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
tylerliu182bc532020-09-25 01:54:45 -0700514 advanceClocks(time::milliseconds(20), 60);
515
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700516 // generate a certificate
tylerliu182bc532020-09-25 01:54:45 -0700517 auto clientIdentity = m_keyChain.createIdentity("/ndn/qwerty");
518 auto clientKey = clientIdentity.getDefaultKey();
519 security::v2::Certificate clientCert;
520 clientCert.setName(Name(clientKey.getName()).append("NDNCERT").append(std::to_string(1473283247810732701)));
521 clientCert.setContentType(tlv::ContentType_Key);
522 clientCert.setFreshnessPeriod(time::hours(24));
523 clientCert.setContent(clientKey.getPublicKey().data(), clientKey.getPublicKey().size());
524 SignatureInfo signatureInfo;
525 signatureInfo.setValidityPeriod(security::ValidityPeriod(time::system_clock::now(),
Zhiyi Zhang46049832020-09-28 17:08:12 -0700526 time::system_clock::now() + time::hours(10)));
tylerliu182bc532020-09-25 01:54:45 -0700527 m_keyChain.sign(clientCert, signingByKey(clientKey.getName()).setSignatureInfo(signatureInfo));
528
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700529 CaProfile item;
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700530 item.m_caPrefix = Name("/ndn");
531 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700532 RequesterState state(m_keyChain, item, RequestType::NEW);
tylerliu182bc532020-09-25 01:54:45 -0700533
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700534 auto interest = Requester::genRevokeInterest(state, clientCert);
tylerliu182bc532020-09-25 01:54:45 -0700535
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700536 bool receiveData = false;
Zhiyi Zhang46049832020-09-28 17:08:12 -0700537 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700538 receiveData = true;
539 auto contentTlv = response.getContent();
540 contentTlv.parse();
541 BOOST_CHECK(static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv_error_code))) != ErrorCode::NO_ERROR);
tylerliu182bc532020-09-25 01:54:45 -0700542 });
543 face.receive(*interest);
544
545 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700546 BOOST_CHECK_EQUAL(receiveData, true);
tylerliu182bc532020-09-25 01:54:45 -0700547}
548
Zhiyi Zhang46049832020-09-28 17:08:12 -0700549BOOST_AUTO_TEST_SUITE_END() // TestCaModule
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800550
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700551} // namespace tests
552} // namespace ndncert
553} // namespace ndn