blob: ff2dcd3c6f3dd4425fe37d2b659009bc8960e27b [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"
Zhiyi Zhang062be6d2020-10-14 17:13:43 -070025#include "detail/info-encoder.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 Zhangaf7c2902019-03-14 22:13:21 -070054 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangcd57da82020-10-08 20:35:40 -070055 auto profileData = ca.getCaProfileData();
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070056
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) {
Zhiyi Zhangcd57da82020-10-08 20:35:40 -070063 if (interest.getName() == profileData.getName()) {
64 face.put(profileData);
65 }
66 },
67 nullptr, nullptr);
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070068 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070069
70 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -070071 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070072 if (count == 0) {
73 count++;
74 auto block = response.getContent();
75 block.parse();
Zhiyi Zhang8f1ade32020-10-14 16:42:57 -070076 infoInterest =std::make_shared<Interest>(Name(block.get(ndn::tlv::Name)).appendSegment(0));
Zhiyi Zhangcd57da82020-10-08 20:35:40 -070077 infoInterest->setCanBePrefix(false);
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070078 }
79 else {
80 count++;
81 BOOST_CHECK(security::verifySignature(response, cert));
82 auto contentBlock = response.getContent();
83 contentBlock.parse();
Zhiyi Zhang8f1ade32020-10-14 16:42:57 -070084 auto caItem = InfoEncoder::decodeDataContent(contentBlock);
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070085 BOOST_CHECK_EQUAL(caItem.m_caPrefix, "/ndn");
86 BOOST_CHECK_EQUAL(caItem.m_probeParameterKeys.size(), 1);
87 BOOST_CHECK_EQUAL(caItem.m_probeParameterKeys.front(), "full name");
88 BOOST_CHECK_EQUAL(caItem.m_cert->wireEncode(), cert.wireEncode());
89 BOOST_CHECK_EQUAL(caItem.m_caInfo, "ndn testbed ca");
90 }
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -070091 });
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080092 face.receive(interest);
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080093 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070094 face.receive(*infoInterest);
95 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangcd57da82020-10-08 20:35:40 -070096
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070097 BOOST_CHECK_EQUAL(count, 2);
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080098}
99
Zhiyi Zhang6f395812020-09-29 14:42:03 -0700100BOOST_AUTO_TEST_CASE(HandleProbe)
101{
102 auto identity = addIdentity(Name("/ndn"));
103 auto key = identity.getDefaultKey();
104 auto cert = key.getDefaultCertificate();
105
106 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700107 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhang6f395812020-09-29 14:42:03 -0700108 advanceClocks(time::milliseconds(20), 60);
109
110 Interest interest("/ndn/CA/PROBE");
111 interest.setCanBePrefix(false);
112
Zhiyi Zhang8f1ade32020-10-14 16:42:57 -0700113 Block paramTLV = makeEmptyBlock(ndn::tlv::ApplicationParameters);
tylerliu50d679e2020-10-14 14:08:39 -0700114 paramTLV.push_back(makeStringBlock(tlv::ParameterKey, "name"));
115 paramTLV.push_back(makeStringBlock(tlv::ParameterValue, "zhiyi"));
Zhiyi Zhang6f395812020-09-29 14:42:03 -0700116 paramTLV.encode();
117
118 interest.setApplicationParameters(paramTLV);
119
120 int count = 0;
121 face.onSendData.connect([&](const Data& response) {
122 count++;
123 BOOST_CHECK(security::verifySignature(response, cert));
124 Block contentBlock = response.getContent();
125 contentBlock.parse();
tylerliu50d679e2020-10-14 14:08:39 -0700126 Block probeResponse = contentBlock.get(tlv::ProbeResponse);
Zhiyi Zhang6f395812020-09-29 14:42:03 -0700127 probeResponse.parse();
128 Name caName;
Zhiyi Zhang8f1ade32020-10-14 16:42:57 -0700129 caName.wireDecode(probeResponse.get(ndn::tlv::Name));
Zhiyi Zhang8683ec92020-10-07 18:18:35 -0700130 BOOST_CHECK_EQUAL(caName.size(), 2);
Zhiyi Zhang6f395812020-09-29 14:42:03 -0700131 });
132 face.receive(interest);
133
134 advanceClocks(time::milliseconds(20), 60);
135 BOOST_CHECK_EQUAL(count, 1);
136}
137
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700138BOOST_AUTO_TEST_CASE(HandleProbeUsingDefaultHandler)
139{
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700140 auto identity = addIdentity(Name("/ndn"));
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700141 auto key = identity.getDefaultKey();
142 auto cert = key.getDefaultCertificate();
143
Zhiyi Zhang22998612020-09-25 14:43:23 -0700144 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700145 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700146 advanceClocks(time::milliseconds(20), 60);
147
swa770de007bc2020-03-24 21:26:21 -0700148 Interest interest("/ndn/CA/PROBE");
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700149 interest.setCanBePrefix(false);
Suyong Won7968f7a2020-05-12 01:01:25 -0700150
Zhiyi Zhang8f1ade32020-10-14 16:42:57 -0700151 Block paramTLV = makeEmptyBlock(ndn::tlv::ApplicationParameters);
tylerliu50d679e2020-10-14 14:08:39 -0700152 paramTLV.push_back(makeStringBlock(tlv::ParameterKey, "name"));
153 paramTLV.push_back(makeStringBlock(tlv::ParameterValue, "zhiyi"));
Suyong Won7968f7a2020-05-12 01:01:25 -0700154 paramTLV.encode();
155
156 interest.setApplicationParameters(paramTLV);
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700157
158 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700159 face.onSendData.connect([&](const Data& response) {
160 count++;
161 BOOST_CHECK(security::verifySignature(response, cert));
162 auto contentBlock = response.getContent();
163 contentBlock.parse();
tylerliu50d679e2020-10-14 14:08:39 -0700164 auto probeResponseBlock = contentBlock.get(tlv::ProbeResponse);
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700165 probeResponseBlock.parse();
166 Name caPrefix;
Zhiyi Zhang8f1ade32020-10-14 16:42:57 -0700167 caPrefix.wireDecode(probeResponseBlock.get(ndn::tlv::Name));
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700168 BOOST_CHECK(caPrefix != "");
169 });
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700170 face.receive(interest);
171
172 advanceClocks(time::milliseconds(20), 60);
173 BOOST_CHECK_EQUAL(count, 1);
174}
175
Suyong Wone2afeb52020-10-04 03:05:39 +0900176BOOST_AUTO_TEST_CASE(HandleProbeRedirection)
177{
178 auto identity = addIdentity(Name("/ndn"));
179 auto key = identity.getDefaultKey();
180 auto cert = key.getDefaultCertificate();
181
182 util::DummyClientFace face(io, m_keyChain, {true, true});
183 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-5", "ca-storage-memory");
Suyong Wone2afeb52020-10-04 03:05:39 +0900184 advanceClocks(time::milliseconds(20), 60);
185
186 Interest interest("/ndn/CA/PROBE");
187 interest.setCanBePrefix(false);
188
Zhiyi Zhang8f1ade32020-10-14 16:42:57 -0700189 Block paramTLV = makeEmptyBlock(ndn::tlv::ApplicationParameters);
tylerliu50d679e2020-10-14 14:08:39 -0700190 paramTLV.push_back(makeStringBlock(tlv::ParameterKey, "name"));
191 paramTLV.push_back(makeStringBlock(tlv::ParameterValue, "zhiyi"));
Suyong Wone2afeb52020-10-04 03:05:39 +0900192 paramTLV.encode();
193
194 interest.setApplicationParameters(paramTLV);
195
196 int count = 0;
197 face.onSendData.connect([&](const Data& response) {
198 count++;
199 BOOST_CHECK(security::verifySignature(response, cert));
200 Block contentBlock = response.getContent();
201 contentBlock.parse();
202
203 // Test CA sent redirections
Zhiyi Zhang34a8d432020-10-03 22:14:25 -0700204 std::vector<Name> redirectionItems;
205 for (auto item : contentBlock.elements()) {
tylerliu50d679e2020-10-14 14:08:39 -0700206 if (item.type() == tlv::ProbeRedirect) {
Zhiyi Zhang34a8d432020-10-03 22:14:25 -0700207 redirectionItems.push_back(Name(item.blockFromValue()));
208 }
Suyong Wone2afeb52020-10-04 03:05:39 +0900209 }
Zhiyi Zhang34a8d432020-10-03 22:14:25 -0700210 BOOST_CHECK_EQUAL(redirectionItems.size(), 2);
tylerliua7bea662020-10-08 18:51:02 -0700211 BOOST_CHECK_EQUAL(security::extractIdentityFromCertName(redirectionItems[0].getPrefix(-1)), "/ndn/site1");
212 BOOST_CHECK_EQUAL(security::extractIdentityFromCertName(redirectionItems[1].getPrefix(-1)), "/ndn/site1");
Suyong Wone2afeb52020-10-04 03:05:39 +0900213 });
214 face.receive(interest);
215 advanceClocks(time::milliseconds(20), 60);
216 BOOST_CHECK_EQUAL(count, 1);
217}
218
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800219BOOST_AUTO_TEST_CASE(HandleNew)
220{
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700221 auto identity = addIdentity(Name("/ndn"));
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800222 auto key = identity.getDefaultKey();
223 auto cert = key.getDefaultCertificate();
224
Zhiyi Zhang22998612020-09-25 14:43:23 -0700225 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700226 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800227 advanceClocks(time::milliseconds(20), 60);
228
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700229 CaProfile item;
Suyong Won256c9062020-05-11 02:45:56 -0700230 item.m_caPrefix = Name("/ndn");
tylerliua7bea662020-10-08 18:51:02 -0700231 item.m_cert = std::make_shared<security::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700232 RequesterState state(m_keyChain, item, RequestType::NEW);
233 auto interest = Requester::genNewInterest(state, Name("/ndn/zhiyi"),
234 time::system_clock::now(),
235 time::system_clock::now() + time::days(1));
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800236
237 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700238 face.onSendData.connect([&](const Data& response) {
239 count++;
240 BOOST_CHECK(security::verifySignature(response, cert));
241 auto contentBlock = response.getContent();
242 contentBlock.parse();
Suyong Won7968f7a2020-05-12 01:01:25 -0700243
tylerliu50d679e2020-10-14 14:08:39 -0700244 BOOST_CHECK(readString(contentBlock.get(tlv::EcdhPub)) != "");
245 BOOST_CHECK(readString(contentBlock.get(tlv::Salt)) != "");
246 BOOST_CHECK(readString(contentBlock.get(tlv::RequestId)) != "");
Suyong Won7968f7a2020-05-12 01:01:25 -0700247
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700248 auto challengeBlockCount = 0;
249 for (auto const& element : contentBlock.elements()) {
tylerliu50d679e2020-10-14 14:08:39 -0700250 if (element.type() == tlv::Challenge) {
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700251 challengeBlockCount++;
Suyong Won7968f7a2020-05-12 01:01:25 -0700252 }
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700253 }
Suyong Won7968f7a2020-05-12 01:01:25 -0700254
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700255 BOOST_CHECK(challengeBlockCount != 0);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700256
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700257 auto challengeList = Requester::onNewRenewRevokeResponse(state, response);
Zhiyi Zhang8fdb36b2020-10-18 11:58:51 -0700258 RequestID requestId;
259 std::memcpy(requestId.data(), contentBlock.get(tlv::RequestId).value(), contentBlock.get(tlv::RequestId).value_size());
260 auto ca_encryption_key = ca.getCaStorage()->getRequest(requestId).m_encryptionKey;
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700261 BOOST_CHECK_EQUAL_COLLECTIONS(state.m_aesKey, state.m_aesKey + sizeof(state.m_aesKey),
tylerliu8e170d62020-09-30 01:31:53 -0700262 ca_encryption_key.value(), ca_encryption_key.value() + ca_encryption_key.value_size());
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700263 });
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700264 face.receive(*interest);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800265
266 advanceClocks(time::milliseconds(20), 60);
267 BOOST_CHECK_EQUAL(count, 1);
268}
269
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700270BOOST_AUTO_TEST_CASE(HandleNewWithInvalidValidityPeriod1)
271{
272 auto identity = addIdentity(Name("/ndn"));
273 auto key = identity.getDefaultKey();
274 auto cert = key.getDefaultCertificate();
275
Zhiyi Zhang22998612020-09-25 14:43:23 -0700276 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700277 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1");
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700278 advanceClocks(time::milliseconds(20), 60);
279
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700280 CaProfile item;
Suyong Won256c9062020-05-11 02:45:56 -0700281 item.m_caPrefix = Name("/ndn");
tylerliua7bea662020-10-08 18:51:02 -0700282 item.m_cert = std::make_shared<security::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700283 RequesterState state(m_keyChain, item, RequestType::NEW);
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700284 auto current_tp = time::system_clock::now();
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700285 auto interest1 = Requester::genNewInterest(state, Name("/ndn/zhiyi"), current_tp, current_tp - time::hours(1));
286 auto interest2 = Requester::genNewInterest(state, Name("/ndn/zhiyi"), current_tp, current_tp + time::days(361));
287 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 -0700288 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700289 auto contentTlv = response.getContent();
290 contentTlv.parse();
tylerliu50d679e2020-10-14 14:08:39 -0700291 auto errorCode = static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv::ErrorCode)));
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700292 BOOST_CHECK(errorCode != ErrorCode::NO_ERROR);
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700293 });
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700294 face.receive(*interest1);
295 face.receive(*interest2);
296 face.receive(*interest3);
297
298 advanceClocks(time::milliseconds(20), 60);
299}
300
tylerliu0b6d0db2020-09-28 17:52:02 -0700301BOOST_AUTO_TEST_CASE(HandleNewWithLongSuffix)
302{
303 auto identity = addIdentity(Name("/ndn"));
304 auto key = identity.getDefaultKey();
305 auto cert = key.getDefaultCertificate();
306
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700307 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700308 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
tylerliu0b6d0db2020-09-28 17:52:02 -0700309 advanceClocks(time::milliseconds(20), 60);
310
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700311 CaProfile item;
tylerliu0b6d0db2020-09-28 17:52:02 -0700312 item.m_caPrefix = Name("/ndn");
tylerliua7bea662020-10-08 18:51:02 -0700313 item.m_cert = std::make_shared<security::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700314 RequesterState state(m_keyChain, item, RequestType::NEW);
tylerliu0b6d0db2020-09-28 17:52:02 -0700315
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700316 auto interest1 = Requester::genNewInterest(state, Name("/ndn/a"), time::system_clock::now(),
317 time::system_clock::now() + time::days(1));
318 auto interest2 = Requester::genNewInterest(state, Name("/ndn/a/b"), time::system_clock::now(),
319 time::system_clock::now() + time::days(1));
320 auto interest3 = Requester::genNewInterest(state, Name("/ndn/a/b/c/d"), time::system_clock::now(),
321 time::system_clock::now() + time::days(1));
tylerliu0b6d0db2020-09-28 17:52:02 -0700322
tylerliu0b6d0db2020-09-28 17:52:02 -0700323 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700324 auto contentTlv = response.getContent();
325 contentTlv.parse();
326 if (interest3->getName().isPrefixOf(response.getName())) {
tylerliu50d679e2020-10-14 14:08:39 -0700327 auto errorCode = static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv::ErrorCode)));
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700328 BOOST_CHECK(errorCode != ErrorCode::NO_ERROR);
329 }
330 else {
331 // should successfully get responses
tylerliu50d679e2020-10-14 14:08:39 -0700332 BOOST_CHECK_EXCEPTION(readNonNegativeInteger(contentTlv.get(tlv::ErrorCode)), std::runtime_error,
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700333 [](const auto& e) { return true; });
334 }
tylerliu0b6d0db2020-09-28 17:52:02 -0700335 });
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700336 face.receive(*interest1);
337 face.receive(*interest2);
338 face.receive(*interest3);
tylerliu0b6d0db2020-09-28 17:52:02 -0700339 advanceClocks(time::milliseconds(20), 60);
tylerliu0b6d0db2020-09-28 17:52:02 -0700340}
341
tylerliu0b6d0db2020-09-28 17:52:02 -0700342BOOST_AUTO_TEST_CASE(HandleNewWithInvalidLength1)
343{
344 auto identity = addIdentity(Name("/ndn"));
345 auto key = identity.getDefaultKey();
346 auto cert = key.getDefaultCertificate();
347
348 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700349 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1");
tylerliu0b6d0db2020-09-28 17:52:02 -0700350 advanceClocks(time::milliseconds(20), 60);
351
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700352 CaProfile item;
tylerliu0b6d0db2020-09-28 17:52:02 -0700353 item.m_caPrefix = Name("/ndn");
tylerliua7bea662020-10-08 18:51:02 -0700354 item.m_cert = std::make_shared<security::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700355 RequesterState state(m_keyChain, item, RequestType::NEW);
356
tylerliu0b6d0db2020-09-28 17:52:02 -0700357 auto current_tp = time::system_clock::now();
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700358 auto interest1 = Requester::genNewInterest(state, Name("/ndn"), current_tp, current_tp + time::days(1));
359 auto interest2 = Requester::genNewInterest(state, Name("/ndn/a/b/c/d"), current_tp, current_tp + time::days(1));
tylerliu0b6d0db2020-09-28 17:52:02 -0700360 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700361 auto contentTlv = response.getContent();
362 contentTlv.parse();
tylerliu50d679e2020-10-14 14:08:39 -0700363 auto errorCode = static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv::ErrorCode)));
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700364 BOOST_CHECK(errorCode != ErrorCode::NO_ERROR);
tylerliu0b6d0db2020-09-28 17:52:02 -0700365 });
366 face.receive(*interest1);
367 face.receive(*interest2);
368
369 advanceClocks(time::milliseconds(20), 60);
370}
371
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700372BOOST_AUTO_TEST_CASE(HandleChallenge)
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800373{
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700374 auto identity = addIdentity(Name("/ndn"));
375 auto key = identity.getDefaultKey();
376 auto cert = key.getDefaultCertificate();
377
Zhiyi Zhang22998612020-09-25 14:43:23 -0700378 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700379 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800380 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700381
382 // generate NEW Interest
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700383 CaProfile item;
Suyong Won256c9062020-05-11 02:45:56 -0700384 item.m_caPrefix = Name("/ndn");
tylerliua7bea662020-10-08 18:51:02 -0700385 item.m_cert = std::make_shared<security::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700386 RequesterState state(m_keyChain, item, RequestType::NEW);
387
388 auto newInterest = Requester::genNewInterest(state, Name("/ndn/zhiyi"), time::system_clock::now(),
389 time::system_clock::now() + time::days(1));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700390
391 // generate CHALLENGE Interest
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700392 shared_ptr<Interest> challengeInterest = nullptr;
393 shared_ptr<Interest> challengeInterest2 = nullptr;
394 shared_ptr<Interest> challengeInterest3 = nullptr;
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800395
396 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700397 face.onSendData.connect([&](const Data& response) {
swa770de007bc2020-03-24 21:26:21 -0700398 if (Name("/ndn/CA/NEW").isPrefixOf(response.getName())) {
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700399 auto challengeList = Requester::onNewRenewRevokeResponse(state, response);
400 auto paramList = Requester::selectOrContinueChallenge(state, "pin");
401 challengeInterest = Requester::genChallengeInterest(state, std::move(paramList));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700402 }
swa770de007bc2020-03-24 21:26:21 -0700403 else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 0) {
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800404 count++;
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700405 BOOST_CHECK(security::verifySignature(response, cert));
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800406
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700407 Requester::onChallengeResponse(state, response);
408 BOOST_CHECK(state.m_status == Status::CHALLENGE);
409 BOOST_CHECK_EQUAL(state.m_challengeStatus, ChallengePin::NEED_CODE);
410 auto paramList = Requester::selectOrContinueChallenge(state, "pin");
411 challengeInterest2 = Requester::genChallengeInterest(state, std::move(paramList));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700412 }
swa770de007bc2020-03-24 21:26:21 -0700413 else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 1) {
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700414 count++;
415 BOOST_CHECK(security::verifySignature(response, cert));
416
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700417 Requester::onChallengeResponse(state, response);
418 BOOST_CHECK(state.m_status == Status::CHALLENGE);
419 BOOST_CHECK_EQUAL(state.m_challengeStatus, ChallengePin::WRONG_CODE);
Davide Pesavento914d05f2019-07-13 16:20:19 -0400420
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700421 auto paramList = Requester::selectOrContinueChallenge(state, "pin");
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700422 auto request = ca.getCertificateRequest(*challengeInterest2);
Zhiyi Zhang8fdb36b2020-10-18 11:58:51 -0700423 auto secret = request->m_challengeState->m_secrets.get(ChallengePin::PARAMETER_KEY_CODE, "");
Zhiyi Zhang46049832020-09-28 17:08:12 -0700424 std::get<1>(paramList[0]) = secret;
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700425 challengeInterest3 = Requester::genChallengeInterest(state, std::move(paramList));
426 std::cout << "CHALLENGE Interest Size: " << challengeInterest3->wireEncode().size() << std::endl;
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700427 }
swa770de007bc2020-03-24 21:26:21 -0700428 else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 2) {
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700429 count++;
430 BOOST_CHECK(security::verifySignature(response, cert));
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700431 Requester::onChallengeResponse(state, response);
432 BOOST_CHECK(state.m_status == Status::SUCCESS);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700433 }
Davide Pesavento914d05f2019-07-13 16:20:19 -0400434 });
435
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700436 face.receive(*newInterest);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800437 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700438 face.receive(*challengeInterest);
439 advanceClocks(time::milliseconds(20), 60);
440 face.receive(*challengeInterest2);
441 advanceClocks(time::milliseconds(20), 60);
442 face.receive(*challengeInterest3);
443 advanceClocks(time::milliseconds(20), 60);
444 BOOST_CHECK_EQUAL(count, 3);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800445}
446
tylerliu182bc532020-09-25 01:54:45 -0700447BOOST_AUTO_TEST_CASE(HandleRevoke)
448{
449 auto identity = addIdentity(Name("/ndn"));
450 auto key = identity.getDefaultKey();
451 auto cert = key.getDefaultCertificate();
452
Zhiyi Zhang46049832020-09-28 17:08:12 -0700453 util::DummyClientFace face(io, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700454 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
tylerliu182bc532020-09-25 01:54:45 -0700455 advanceClocks(time::milliseconds(20), 60);
456
457 //generate a certificate
458 auto clientIdentity = m_keyChain.createIdentity("/ndn/qwerty");
459 auto clientKey = clientIdentity.getDefaultKey();
tylerliua7bea662020-10-08 18:51:02 -0700460 security::Certificate clientCert;
tylerliu182bc532020-09-25 01:54:45 -0700461 clientCert.setName(Name(clientKey.getName()).append("cert-request").appendVersion());
Zhiyi Zhang8f1ade32020-10-14 16:42:57 -0700462 clientCert.setContentType(ndn::tlv::ContentType_Key);
tylerliu182bc532020-09-25 01:54:45 -0700463 clientCert.setFreshnessPeriod(time::hours(24));
464 clientCert.setContent(clientKey.getPublicKey().data(), clientKey.getPublicKey().size());
465 SignatureInfo signatureInfo;
466 signatureInfo.setValidityPeriod(security::ValidityPeriod(time::system_clock::now(),
Zhiyi Zhang46049832020-09-28 17:08:12 -0700467 time::system_clock::now() + time::hours(10)));
tylerliu182bc532020-09-25 01:54:45 -0700468 m_keyChain.sign(clientCert, signingByKey(clientKey.getName()).setSignatureInfo(signatureInfo));
Zhiyi Zhang8fdb36b2020-10-18 11:58:51 -0700469 RequestID requestId = {1,2,3,4,5,6,7,8};
470 CaState certRequest(Name("/ndn"), requestId, RequestType::NEW, Status::SUCCESS, clientCert, makeEmptyBlock(ndn::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");
tylerliua7bea662020-10-08 18:51:02 -0700475 item.m_cert = std::make_shared<security::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
tylerliu50d679e2020-10-14 14:08:39 -0700487 BOOST_CHECK(readString(contentBlock.get(tlv::EcdhPub)) != "");
488 BOOST_CHECK(readString(contentBlock.get(tlv::Salt)) != "");
489 BOOST_CHECK(readString(contentBlock.get(tlv::RequestId)) != "");
tylerliu182bc532020-09-25 01:54:45 -0700490
491 auto challengeBlockCount = 0;
492 for (auto const& element : contentBlock.elements()) {
tylerliu50d679e2020-10-14 14:08:39 -0700493 if (element.type() == tlv::Challenge) {
Zhiyi Zhang46049832020-09-28 17:08:12 -0700494 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);
Zhiyi Zhang8fdb36b2020-10-18 11:58:51 -0700501 RequestID requestId;
502 std::memcpy(requestId.data(), contentBlock.get(tlv::RequestId).value(), contentBlock.get(tlv::RequestId).value_size());
503 auto ca_encryption_key = ca.getCaStorage()->getRequest(requestId).m_encryptionKey;
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700504 BOOST_CHECK_EQUAL_COLLECTIONS(state.m_aesKey, state.m_aesKey + sizeof(state.m_aesKey),
tylerliu8e170d62020-09-30 01:31:53 -0700505 ca_encryption_key.value(), ca_encryption_key.value() + ca_encryption_key.value_size());
tylerliu182bc532020-09-25 01:54:45 -0700506 });
507 face.receive(*interest);
508
509 advanceClocks(time::milliseconds(20), 60);
510 BOOST_CHECK_EQUAL(count, 1);
511}
512
513BOOST_AUTO_TEST_CASE(HandleRevokeWithBadCert)
514{
515 auto identity = addIdentity(Name("/ndn"));
516 auto key = identity.getDefaultKey();
517 auto cert = key.getDefaultCertificate();
518
Zhiyi Zhang46049832020-09-28 17:08:12 -0700519 util::DummyClientFace face(io, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700520 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
tylerliu182bc532020-09-25 01:54:45 -0700521 advanceClocks(time::milliseconds(20), 60);
522
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700523 // generate a certificate
tylerliu182bc532020-09-25 01:54:45 -0700524 auto clientIdentity = m_keyChain.createIdentity("/ndn/qwerty");
525 auto clientKey = clientIdentity.getDefaultKey();
tylerliua7bea662020-10-08 18:51:02 -0700526 security::Certificate clientCert;
tylerliu182bc532020-09-25 01:54:45 -0700527 clientCert.setName(Name(clientKey.getName()).append("NDNCERT").append(std::to_string(1473283247810732701)));
Zhiyi Zhang8f1ade32020-10-14 16:42:57 -0700528 clientCert.setContentType(ndn::tlv::ContentType_Key);
tylerliu182bc532020-09-25 01:54:45 -0700529 clientCert.setFreshnessPeriod(time::hours(24));
530 clientCert.setContent(clientKey.getPublicKey().data(), clientKey.getPublicKey().size());
531 SignatureInfo signatureInfo;
532 signatureInfo.setValidityPeriod(security::ValidityPeriod(time::system_clock::now(),
Zhiyi Zhang46049832020-09-28 17:08:12 -0700533 time::system_clock::now() + time::hours(10)));
tylerliu182bc532020-09-25 01:54:45 -0700534 m_keyChain.sign(clientCert, signingByKey(clientKey.getName()).setSignatureInfo(signatureInfo));
535
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700536 CaProfile item;
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700537 item.m_caPrefix = Name("/ndn");
tylerliua7bea662020-10-08 18:51:02 -0700538 item.m_cert = std::make_shared<security::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700539 RequesterState state(m_keyChain, item, RequestType::NEW);
tylerliu182bc532020-09-25 01:54:45 -0700540
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700541 auto interest = Requester::genRevokeInterest(state, clientCert);
tylerliu182bc532020-09-25 01:54:45 -0700542
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700543 bool receiveData = false;
Zhiyi Zhang46049832020-09-28 17:08:12 -0700544 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700545 receiveData = true;
546 auto contentTlv = response.getContent();
547 contentTlv.parse();
tylerliu50d679e2020-10-14 14:08:39 -0700548 BOOST_CHECK(static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv::ErrorCode))) != ErrorCode::NO_ERROR);
tylerliu182bc532020-09-25 01:54:45 -0700549 });
550 face.receive(*interest);
551
552 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700553 BOOST_CHECK_EQUAL(receiveData, true);
tylerliu182bc532020-09-25 01:54:45 -0700554}
555
Zhiyi Zhang46049832020-09-28 17:08:12 -0700556BOOST_AUTO_TEST_SUITE_END() // TestCaModule
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800557
Zhiyi Zhange4891b72020-10-10 15:11:57 -0700558} // namespace tests
559} // namespace ndncert
560} // namespace ndn