blob: 3c4dbb48264d76c97a8035717e581c933d42a3b3 [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 Zhang84e11842020-11-19 20:03:23 -080022#include "challenge/challenge-module.hpp"
23#include "challenge/challenge-email.hpp"
24#include "challenge/challenge-pin.hpp"
Zhiyi Zhang062be6d2020-10-14 17:13:43 -070025#include "detail/info-encoder.hpp"
tylerliu4140fe82021-01-27 15:45:44 -080026#include "requester-request.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 Zhang32d4b4e2020-10-28 22:10:49 -070033using namespace ca;
34
Zhiyi Zhangae123bf2017-04-14 12:24:53 -070035BOOST_FIXTURE_TEST_SUITE(TestCaModule, DatabaseFixture)
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080036
37BOOST_AUTO_TEST_CASE(Initialization)
38{
Zhiyi Zhang22998612020-09-25 14:43:23 -070039 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -070040 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhang44c6a352020-12-14 10:57:17 -080041 BOOST_CHECK_EQUAL(ca.getCaConf().caProfile.caPrefix, "/ndn");
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080042
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080043 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070044 BOOST_CHECK_EQUAL(ca.m_registeredPrefixHandles.size(), 1); // removed local discovery registration
Zhiyi Zhang696cd042020-10-07 21:27:36 -070045 BOOST_CHECK_EQUAL(ca.m_interestFilterHandles.size(), 5); // infoMeta, onProbe, onNew, onChallenge, onRevoke
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080046}
47
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070048BOOST_AUTO_TEST_CASE(HandleProfileFetching)
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070049{
Zhiyi Zhang615b6b72021-01-11 14:25:32 -080050 name::setConventionEncoding(name::Convention::TYPED);
51
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070052 auto identity = addIdentity(Name("/ndn"));
53 auto key = identity.getDefaultKey();
54 auto cert = key.getDefaultCertificate();
55
Zhiyi Zhang22998612020-09-25 14:43:23 -070056 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -070057 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070058 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangcd57da82020-10-08 20:35:40 -070059 auto profileData = ca.getCaProfileData();
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070060
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070061 Interest interest = MetadataObject::makeDiscoveryInterest(Name("/ndn/CA/INFO"));
62 shared_ptr<Interest> infoInterest = nullptr;
63
Zhiyi Zhang696cd042020-10-07 21:27:36 -070064 face.setInterestFilter(
65 InterestFilter("/ndn/CA/INFO"),
66 [&](const auto&, const Interest& interest) {
Zhiyi Zhangcd57da82020-10-08 20:35:40 -070067 if (interest.getName() == profileData.getName()) {
68 face.put(profileData);
69 }
70 },
71 nullptr, nullptr);
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070072 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070073
74 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -070075 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070076 if (count == 0) {
77 count++;
78 auto block = response.getContent();
79 block.parse();
Zhiyi Zhang8f1ade32020-10-14 16:42:57 -070080 infoInterest =std::make_shared<Interest>(Name(block.get(ndn::tlv::Name)).appendSegment(0));
Zhiyi Zhangcd57da82020-10-08 20:35:40 -070081 infoInterest->setCanBePrefix(false);
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070082 }
83 else {
84 count++;
85 BOOST_CHECK(security::verifySignature(response, cert));
86 auto contentBlock = response.getContent();
87 contentBlock.parse();
Zhiyi Zhangf22ae242020-11-17 10:51:15 -080088 auto caItem = infotlv::decodeDataContent(contentBlock);
Zhiyi Zhang44c6a352020-12-14 10:57:17 -080089 BOOST_CHECK_EQUAL(caItem.caPrefix, "/ndn");
90 BOOST_CHECK_EQUAL(caItem.probeParameterKeys.size(), 1);
91 BOOST_CHECK_EQUAL(caItem.probeParameterKeys.front(), "full name");
92 BOOST_CHECK_EQUAL(caItem.cert->wireEncode(), cert.wireEncode());
93 BOOST_CHECK_EQUAL(caItem.caInfo, "ndn testbed ca");
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070094 }
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);
Zhiyi Zhangcd57da82020-10-08 20:35:40 -0700100
Zhiyi Zhangfbcab842020-10-07 15:17:13 -0700101 BOOST_CHECK_EQUAL(count, 2);
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800102}
103
Zhiyi Zhang6f395812020-09-29 14:42:03 -0700104BOOST_AUTO_TEST_CASE(HandleProbe)
105{
106 auto identity = addIdentity(Name("/ndn"));
107 auto key = identity.getDefaultKey();
108 auto cert = key.getDefaultCertificate();
109
110 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700111 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhang6f395812020-09-29 14:42:03 -0700112 advanceClocks(time::milliseconds(20), 60);
113
114 Interest interest("/ndn/CA/PROBE");
115 interest.setCanBePrefix(false);
116
Zhiyi Zhang8f1ade32020-10-14 16:42:57 -0700117 Block paramTLV = makeEmptyBlock(ndn::tlv::ApplicationParameters);
tylerliu50d679e2020-10-14 14:08:39 -0700118 paramTLV.push_back(makeStringBlock(tlv::ParameterKey, "name"));
119 paramTLV.push_back(makeStringBlock(tlv::ParameterValue, "zhiyi"));
Zhiyi Zhang6f395812020-09-29 14:42:03 -0700120 paramTLV.encode();
121
122 interest.setApplicationParameters(paramTLV);
123
124 int count = 0;
125 face.onSendData.connect([&](const Data& response) {
126 count++;
127 BOOST_CHECK(security::verifySignature(response, cert));
128 Block contentBlock = response.getContent();
129 contentBlock.parse();
tylerliu50d679e2020-10-14 14:08:39 -0700130 Block probeResponse = contentBlock.get(tlv::ProbeResponse);
Zhiyi Zhang6f395812020-09-29 14:42:03 -0700131 probeResponse.parse();
132 Name caName;
Zhiyi Zhang8f1ade32020-10-14 16:42:57 -0700133 caName.wireDecode(probeResponse.get(ndn::tlv::Name));
Zhiyi Zhang8683ec92020-10-07 18:18:35 -0700134 BOOST_CHECK_EQUAL(caName.size(), 2);
Zhiyi Zhang6f395812020-09-29 14:42:03 -0700135 });
136 face.receive(interest);
137
138 advanceClocks(time::milliseconds(20), 60);
139 BOOST_CHECK_EQUAL(count, 1);
140}
141
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700142BOOST_AUTO_TEST_CASE(HandleProbeUsingDefaultHandler)
143{
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700144 auto identity = addIdentity(Name("/ndn"));
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700145 auto key = identity.getDefaultKey();
146 auto cert = key.getDefaultCertificate();
147
Zhiyi Zhang22998612020-09-25 14:43:23 -0700148 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700149 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700150 advanceClocks(time::milliseconds(20), 60);
151
swa770de007bc2020-03-24 21:26:21 -0700152 Interest interest("/ndn/CA/PROBE");
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700153 interest.setCanBePrefix(false);
Suyong Won7968f7a2020-05-12 01:01:25 -0700154
Zhiyi Zhang8f1ade32020-10-14 16:42:57 -0700155 Block paramTLV = makeEmptyBlock(ndn::tlv::ApplicationParameters);
tylerliu50d679e2020-10-14 14:08:39 -0700156 paramTLV.push_back(makeStringBlock(tlv::ParameterKey, "name"));
157 paramTLV.push_back(makeStringBlock(tlv::ParameterValue, "zhiyi"));
Suyong Won7968f7a2020-05-12 01:01:25 -0700158 paramTLV.encode();
159
160 interest.setApplicationParameters(paramTLV);
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700161
162 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700163 face.onSendData.connect([&](const Data& response) {
164 count++;
165 BOOST_CHECK(security::verifySignature(response, cert));
166 auto contentBlock = response.getContent();
167 contentBlock.parse();
tylerliu50d679e2020-10-14 14:08:39 -0700168 auto probeResponseBlock = contentBlock.get(tlv::ProbeResponse);
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700169 probeResponseBlock.parse();
170 Name caPrefix;
Zhiyi Zhang8f1ade32020-10-14 16:42:57 -0700171 caPrefix.wireDecode(probeResponseBlock.get(ndn::tlv::Name));
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700172 BOOST_CHECK(caPrefix != "");
173 });
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700174 face.receive(interest);
175
176 advanceClocks(time::milliseconds(20), 60);
177 BOOST_CHECK_EQUAL(count, 1);
178}
179
Suyong Wone2afeb52020-10-04 03:05:39 +0900180BOOST_AUTO_TEST_CASE(HandleProbeRedirection)
181{
182 auto identity = addIdentity(Name("/ndn"));
183 auto key = identity.getDefaultKey();
184 auto cert = key.getDefaultCertificate();
185
186 util::DummyClientFace face(io, m_keyChain, {true, true});
187 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-5", "ca-storage-memory");
Suyong Wone2afeb52020-10-04 03:05:39 +0900188 advanceClocks(time::milliseconds(20), 60);
189
190 Interest interest("/ndn/CA/PROBE");
191 interest.setCanBePrefix(false);
192
Zhiyi Zhang8f1ade32020-10-14 16:42:57 -0700193 Block paramTLV = makeEmptyBlock(ndn::tlv::ApplicationParameters);
tylerliu50d679e2020-10-14 14:08:39 -0700194 paramTLV.push_back(makeStringBlock(tlv::ParameterKey, "name"));
195 paramTLV.push_back(makeStringBlock(tlv::ParameterValue, "zhiyi"));
Suyong Wone2afeb52020-10-04 03:05:39 +0900196 paramTLV.encode();
197
198 interest.setApplicationParameters(paramTLV);
199
200 int count = 0;
201 face.onSendData.connect([&](const Data& response) {
202 count++;
203 BOOST_CHECK(security::verifySignature(response, cert));
204 Block contentBlock = response.getContent();
205 contentBlock.parse();
206
207 // Test CA sent redirections
Zhiyi Zhang34a8d432020-10-03 22:14:25 -0700208 std::vector<Name> redirectionItems;
209 for (auto item : contentBlock.elements()) {
tylerliu50d679e2020-10-14 14:08:39 -0700210 if (item.type() == tlv::ProbeRedirect) {
Zhiyi Zhang34a8d432020-10-03 22:14:25 -0700211 redirectionItems.push_back(Name(item.blockFromValue()));
212 }
Suyong Wone2afeb52020-10-04 03:05:39 +0900213 }
Zhiyi Zhang34a8d432020-10-03 22:14:25 -0700214 BOOST_CHECK_EQUAL(redirectionItems.size(), 2);
tylerliua7bea662020-10-08 18:51:02 -0700215 BOOST_CHECK_EQUAL(security::extractIdentityFromCertName(redirectionItems[0].getPrefix(-1)), "/ndn/site1");
216 BOOST_CHECK_EQUAL(security::extractIdentityFromCertName(redirectionItems[1].getPrefix(-1)), "/ndn/site1");
Suyong Wone2afeb52020-10-04 03:05:39 +0900217 });
218 face.receive(interest);
219 advanceClocks(time::milliseconds(20), 60);
220 BOOST_CHECK_EQUAL(count, 1);
221}
222
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800223BOOST_AUTO_TEST_CASE(HandleNew)
224{
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700225 auto identity = addIdentity(Name("/ndn"));
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800226 auto key = identity.getDefaultKey();
227 auto cert = key.getDefaultCertificate();
228
Zhiyi Zhang22998612020-09-25 14:43:23 -0700229 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700230 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800231 advanceClocks(time::milliseconds(20), 60);
232
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700233 CaProfile item;
Zhiyi Zhang44c6a352020-12-14 10:57:17 -0800234 item.caPrefix = Name("/ndn");
235 item.cert = std::make_shared<security::Certificate>(cert);
tylerliu4140fe82021-01-27 15:45:44 -0800236 requester::Request state(m_keyChain, item, RequestType::NEW);
237 auto interest = state.genNewInterest(Name("/ndn/zhiyi"),
238 time::system_clock::now(),
239 time::system_clock::now() + time::days(1));
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800240
241 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700242 face.onSendData.connect([&](const Data& response) {
243 count++;
244 BOOST_CHECK(security::verifySignature(response, cert));
245 auto contentBlock = response.getContent();
246 contentBlock.parse();
Suyong Won7968f7a2020-05-12 01:01:25 -0700247
tylerliu50d679e2020-10-14 14:08:39 -0700248 BOOST_CHECK(readString(contentBlock.get(tlv::EcdhPub)) != "");
249 BOOST_CHECK(readString(contentBlock.get(tlv::Salt)) != "");
250 BOOST_CHECK(readString(contentBlock.get(tlv::RequestId)) != "");
Suyong Won7968f7a2020-05-12 01:01:25 -0700251
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700252 auto challengeBlockCount = 0;
253 for (auto const& element : contentBlock.elements()) {
tylerliu50d679e2020-10-14 14:08:39 -0700254 if (element.type() == tlv::Challenge) {
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700255 challengeBlockCount++;
Suyong Won7968f7a2020-05-12 01:01:25 -0700256 }
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700257 }
Suyong Won7968f7a2020-05-12 01:01:25 -0700258
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700259 BOOST_CHECK(challengeBlockCount != 0);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700260
tylerliu4140fe82021-01-27 15:45:44 -0800261 auto challengeList = state.onNewRenewRevokeResponse(response);
Zhiyi Zhangc9ada1b2020-10-29 19:13:15 -0700262 RequestId requestId;
Zhiyi Zhang8fdb36b2020-10-18 11:58:51 -0700263 std::memcpy(requestId.data(), contentBlock.get(tlv::RequestId).value(), contentBlock.get(tlv::RequestId).value_size());
tylerliu7b9185c2020-11-24 12:15:18 -0800264 auto ca_encryption_key = ca.getCaStorage()->getRequest(requestId).encryptionKey;
tylerliuf2e6bb52020-12-13 13:23:05 -0800265 BOOST_CHECK_EQUAL_COLLECTIONS(state.aesKey.begin(), state.aesKey.end(),
Zhiyi Zhang1f9551b2020-10-30 10:30:43 -0700266 ca_encryption_key.begin(), ca_encryption_key.end());
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700267 });
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700268 face.receive(*interest);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800269
270 advanceClocks(time::milliseconds(20), 60);
271 BOOST_CHECK_EQUAL(count, 1);
272}
273
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700274BOOST_AUTO_TEST_CASE(HandleNewWithInvalidValidityPeriod1)
275{
276 auto identity = addIdentity(Name("/ndn"));
277 auto key = identity.getDefaultKey();
278 auto cert = key.getDefaultCertificate();
279
Zhiyi Zhang22998612020-09-25 14:43:23 -0700280 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700281 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1");
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700282 advanceClocks(time::milliseconds(20), 60);
283
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700284 CaProfile item;
Zhiyi Zhang44c6a352020-12-14 10:57:17 -0800285 item.caPrefix = Name("/ndn");
286 item.cert = std::make_shared<security::Certificate>(cert);
tylerliu4140fe82021-01-27 15:45:44 -0800287 requester::Request state(m_keyChain, item, RequestType::NEW);
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700288 auto current_tp = time::system_clock::now();
tylerliu4140fe82021-01-27 15:45:44 -0800289 auto interest1 = state.genNewInterest(Name("/ndn/zhiyi"), current_tp, current_tp - time::hours(1));
290 auto interest2 = state.genNewInterest(Name("/ndn/zhiyi"), current_tp, current_tp + time::days(361));
291 auto interest3 = state.genNewInterest(Name("/ndn/zhiyi"), current_tp - time::hours(1), current_tp + time::hours(2));
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700292 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700293 auto contentTlv = response.getContent();
294 contentTlv.parse();
tylerliu50d679e2020-10-14 14:08:39 -0700295 auto errorCode = static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv::ErrorCode)));
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700296 BOOST_CHECK(errorCode != ErrorCode::NO_ERROR);
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700297 });
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700298 face.receive(*interest1);
299 face.receive(*interest2);
300 face.receive(*interest3);
301
302 advanceClocks(time::milliseconds(20), 60);
303}
304
tylerliuf62cfeb2021-01-28 11:01:33 -0800305BOOST_AUTO_TEST_CASE(HandleNewWithServerBadValidity)
306{
307 auto identity = addIdentity(Name("/ndn"));
308 auto key = identity.getDefaultKey();
309
310 //build expired cert
311 security::Certificate cert;
312 cert.setName(Name(key.getName()).append("self-sign").appendVersion());
313 cert.setContentType(ndn::tlv::ContentType_Key);
314 cert.setContent(key.getPublicKey().data(), key.getPublicKey().size());
315 SignatureInfo signatureInfo;
316 signatureInfo.setValidityPeriod(security::ValidityPeriod(time::system_clock::now() - time::days(1), time::system_clock::now() - time::seconds(1)));
317 m_keyChain.sign(cert, signingByKey(key.getName()).setSignatureInfo(signatureInfo));
318 m_keyChain.setDefaultCertificate(key, cert);
319
320 util::DummyClientFace face(io, m_keyChain, {true, true});
321 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
322 advanceClocks(time::milliseconds(20), 60);
323
324 CaProfile item;
325 item.caPrefix = Name("/ndn");
326 item.cert = std::make_shared<security::Certificate>(cert);
327 requester::Request state(m_keyChain, item, RequestType::NEW);
328 auto interest = state.genNewInterest(Name("/ndn/zhiyi"),
329 time::system_clock::now(),
330 time::system_clock::now() + time::days(1));
331
332 int count = 0;
333 face.onSendData.connect([&](const Data& response) {
334 auto contentTlv = response.getContent();
335 contentTlv.parse();
336 auto errorCode = static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv::ErrorCode)));
337 BOOST_CHECK(errorCode != ErrorCode::NO_ERROR);
338 count ++;
339 });
340 face.receive(*interest);
341
342 advanceClocks(time::milliseconds(20), 60);
343 BOOST_CHECK_EQUAL(count, 1);
344}
345
tylerliu0b6d0db2020-09-28 17:52:02 -0700346BOOST_AUTO_TEST_CASE(HandleNewWithLongSuffix)
347{
348 auto identity = addIdentity(Name("/ndn"));
349 auto key = identity.getDefaultKey();
350 auto cert = key.getDefaultCertificate();
351
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700352 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700353 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
tylerliu0b6d0db2020-09-28 17:52:02 -0700354 advanceClocks(time::milliseconds(20), 60);
355
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700356 CaProfile item;
Zhiyi Zhang44c6a352020-12-14 10:57:17 -0800357 item.caPrefix = Name("/ndn");
358 item.cert = std::make_shared<security::Certificate>(cert);
tylerliu4140fe82021-01-27 15:45:44 -0800359 requester::Request state(m_keyChain, item, RequestType::NEW);
tylerliu0b6d0db2020-09-28 17:52:02 -0700360
tylerliu4140fe82021-01-27 15:45:44 -0800361 auto interest1 = state.genNewInterest(Name("/ndn/a"), time::system_clock::now(),
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700362 time::system_clock::now() + time::days(1));
tylerliu4140fe82021-01-27 15:45:44 -0800363 auto interest2 = state.genNewInterest(Name("/ndn/a/b"), time::system_clock::now(),
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700364 time::system_clock::now() + time::days(1));
tylerliu4140fe82021-01-27 15:45:44 -0800365 auto interest3 = state.genNewInterest(Name("/ndn/a/b/c/d"), time::system_clock::now(),
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700366 time::system_clock::now() + time::days(1));
tylerliu0b6d0db2020-09-28 17:52:02 -0700367
tylerliu0b6d0db2020-09-28 17:52:02 -0700368 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700369 auto contentTlv = response.getContent();
370 contentTlv.parse();
371 if (interest3->getName().isPrefixOf(response.getName())) {
tylerliu50d679e2020-10-14 14:08:39 -0700372 auto errorCode = static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv::ErrorCode)));
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700373 BOOST_CHECK(errorCode != ErrorCode::NO_ERROR);
374 }
375 else {
376 // should successfully get responses
tylerliu50d679e2020-10-14 14:08:39 -0700377 BOOST_CHECK_EXCEPTION(readNonNegativeInteger(contentTlv.get(tlv::ErrorCode)), std::runtime_error,
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700378 [](const auto& e) { return true; });
379 }
tylerliu0b6d0db2020-09-28 17:52:02 -0700380 });
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700381 face.receive(*interest1);
382 face.receive(*interest2);
383 face.receive(*interest3);
tylerliu0b6d0db2020-09-28 17:52:02 -0700384 advanceClocks(time::milliseconds(20), 60);
tylerliu0b6d0db2020-09-28 17:52:02 -0700385}
386
tylerliu0b6d0db2020-09-28 17:52:02 -0700387BOOST_AUTO_TEST_CASE(HandleNewWithInvalidLength1)
388{
389 auto identity = addIdentity(Name("/ndn"));
390 auto key = identity.getDefaultKey();
391 auto cert = key.getDefaultCertificate();
392
393 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700394 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1");
tylerliu0b6d0db2020-09-28 17:52:02 -0700395 advanceClocks(time::milliseconds(20), 60);
396
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700397 CaProfile item;
Zhiyi Zhang44c6a352020-12-14 10:57:17 -0800398 item.caPrefix = Name("/ndn");
399 item.cert = std::make_shared<security::Certificate>(cert);
tylerliu4140fe82021-01-27 15:45:44 -0800400 requester::Request state(m_keyChain, item, RequestType::NEW);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700401
tylerliu0b6d0db2020-09-28 17:52:02 -0700402 auto current_tp = time::system_clock::now();
tylerliu4140fe82021-01-27 15:45:44 -0800403 auto interest1 = state.genNewInterest(Name("/ndn"), current_tp, current_tp + time::days(1));
404 auto interest2 = state.genNewInterest(Name("/ndn/a/b/c/d"), current_tp, current_tp + time::days(1));
tylerliu0b6d0db2020-09-28 17:52:02 -0700405 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700406 auto contentTlv = response.getContent();
407 contentTlv.parse();
tylerliu50d679e2020-10-14 14:08:39 -0700408 auto errorCode = static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv::ErrorCode)));
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700409 BOOST_CHECK(errorCode != ErrorCode::NO_ERROR);
tylerliu0b6d0db2020-09-28 17:52:02 -0700410 });
411 face.receive(*interest1);
412 face.receive(*interest2);
413
414 advanceClocks(time::milliseconds(20), 60);
415}
416
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700417BOOST_AUTO_TEST_CASE(HandleChallenge)
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800418{
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700419 auto identity = addIdentity(Name("/ndn"));
420 auto key = identity.getDefaultKey();
421 auto cert = key.getDefaultCertificate();
422
Zhiyi Zhang22998612020-09-25 14:43:23 -0700423 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700424 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800425 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700426
427 // generate NEW Interest
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700428 CaProfile item;
Zhiyi Zhang44c6a352020-12-14 10:57:17 -0800429 item.caPrefix = Name("/ndn");
430 item.cert = std::make_shared<security::Certificate>(cert);
tylerliu4140fe82021-01-27 15:45:44 -0800431 requester::Request state(m_keyChain, item, RequestType::NEW);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700432
tylerliu4140fe82021-01-27 15:45:44 -0800433 auto newInterest = state.genNewInterest(Name("/ndn/zhiyi"), time::system_clock::now(),
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700434 time::system_clock::now() + time::days(1));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700435
436 // generate CHALLENGE Interest
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700437 shared_ptr<Interest> challengeInterest = nullptr;
438 shared_ptr<Interest> challengeInterest2 = nullptr;
439 shared_ptr<Interest> challengeInterest3 = nullptr;
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800440
441 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700442 face.onSendData.connect([&](const Data& response) {
swa770de007bc2020-03-24 21:26:21 -0700443 if (Name("/ndn/CA/NEW").isPrefixOf(response.getName())) {
tylerliu4140fe82021-01-27 15:45:44 -0800444 auto challengeList = state.onNewRenewRevokeResponse(response);
445 auto paramList = state.selectOrContinueChallenge("pin");
446 challengeInterest = state.genChallengeInterest(std::move(paramList));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700447 }
swa770de007bc2020-03-24 21:26:21 -0700448 else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 0) {
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800449 count++;
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700450 BOOST_CHECK(security::verifySignature(response, cert));
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800451
tylerliu4140fe82021-01-27 15:45:44 -0800452 state.onChallengeResponse(response);
tylerliuf2e6bb52020-12-13 13:23:05 -0800453 BOOST_CHECK(state.status == Status::CHALLENGE);
454 BOOST_CHECK_EQUAL(state.challengeStatus, ChallengePin::NEED_CODE);
tylerliu4140fe82021-01-27 15:45:44 -0800455 auto paramList = state.selectOrContinueChallenge("pin");
456 challengeInterest2 = state.genChallengeInterest(std::move(paramList));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700457 }
swa770de007bc2020-03-24 21:26:21 -0700458 else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 1) {
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700459 count++;
460 BOOST_CHECK(security::verifySignature(response, cert));
461
tylerliu4140fe82021-01-27 15:45:44 -0800462 state.onChallengeResponse(response);
tylerliuf2e6bb52020-12-13 13:23:05 -0800463 BOOST_CHECK(state.status == Status::CHALLENGE);
464 BOOST_CHECK_EQUAL(state.challengeStatus, ChallengePin::WRONG_CODE);
Davide Pesavento914d05f2019-07-13 16:20:19 -0400465
tylerliu4140fe82021-01-27 15:45:44 -0800466 auto paramList = state.selectOrContinueChallenge("pin");
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700467 auto request = ca.getCertificateRequest(*challengeInterest2);
tylerliu7b9185c2020-11-24 12:15:18 -0800468 auto secret = request->challengeState->secrets.get(ChallengePin::PARAMETER_KEY_CODE, "");
tylerliu40226332020-11-11 15:37:16 -0800469 paramList.begin()->second = secret;
tylerliu4140fe82021-01-27 15:45:44 -0800470 challengeInterest3 = state.genChallengeInterest(std::move(paramList));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700471 }
swa770de007bc2020-03-24 21:26:21 -0700472 else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 2) {
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700473 count++;
474 BOOST_CHECK(security::verifySignature(response, cert));
tylerliu4140fe82021-01-27 15:45:44 -0800475 state.onChallengeResponse(response);
tylerliuf2e6bb52020-12-13 13:23:05 -0800476 BOOST_CHECK(state.status == Status::SUCCESS);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700477 }
Davide Pesavento914d05f2019-07-13 16:20:19 -0400478 });
479
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700480 face.receive(*newInterest);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800481 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700482 face.receive(*challengeInterest);
483 advanceClocks(time::milliseconds(20), 60);
484 face.receive(*challengeInterest2);
485 advanceClocks(time::milliseconds(20), 60);
486 face.receive(*challengeInterest3);
487 advanceClocks(time::milliseconds(20), 60);
488 BOOST_CHECK_EQUAL(count, 3);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800489}
490
tylerliu182bc532020-09-25 01:54:45 -0700491BOOST_AUTO_TEST_CASE(HandleRevoke)
492{
493 auto identity = addIdentity(Name("/ndn"));
494 auto key = identity.getDefaultKey();
495 auto cert = key.getDefaultCertificate();
496
Zhiyi Zhang46049832020-09-28 17:08:12 -0700497 util::DummyClientFace face(io, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700498 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
tylerliu182bc532020-09-25 01:54:45 -0700499 advanceClocks(time::milliseconds(20), 60);
500
501 //generate a certificate
502 auto clientIdentity = m_keyChain.createIdentity("/ndn/qwerty");
503 auto clientKey = clientIdentity.getDefaultKey();
tylerliua7bea662020-10-08 18:51:02 -0700504 security::Certificate clientCert;
tylerliu182bc532020-09-25 01:54:45 -0700505 clientCert.setName(Name(clientKey.getName()).append("cert-request").appendVersion());
Zhiyi Zhang8f1ade32020-10-14 16:42:57 -0700506 clientCert.setContentType(ndn::tlv::ContentType_Key);
tylerliu182bc532020-09-25 01:54:45 -0700507 clientCert.setFreshnessPeriod(time::hours(24));
508 clientCert.setContent(clientKey.getPublicKey().data(), clientKey.getPublicKey().size());
509 SignatureInfo signatureInfo;
510 signatureInfo.setValidityPeriod(security::ValidityPeriod(time::system_clock::now(),
Zhiyi Zhang46049832020-09-28 17:08:12 -0700511 time::system_clock::now() + time::hours(10)));
tylerliu182bc532020-09-25 01:54:45 -0700512 m_keyChain.sign(clientCert, signingByKey(clientKey.getName()).setSignatureInfo(signatureInfo));
Zhiyi Zhang1f5e86e2020-12-04 15:07:57 -0800513 RequestId requestId = {{101}};
514 RequestState certRequest;
515 certRequest.caPrefix = Name("/ndn");
516 certRequest.requestId = requestId;
517 certRequest.requestType = RequestType::NEW;
518 certRequest.status = Status::SUCCESS;
519 certRequest.cert = clientCert;
tylerliu182bc532020-09-25 01:54:45 -0700520 auto issuedCert = ca.issueCertificate(certRequest);
521
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700522 CaProfile item;
Zhiyi Zhang44c6a352020-12-14 10:57:17 -0800523 item.caPrefix = Name("/ndn");
524 item.cert = std::make_shared<security::Certificate>(cert);
tylerliu4140fe82021-01-27 15:45:44 -0800525 requester::Request state(m_keyChain, item, RequestType::REVOKE);
tylerliu182bc532020-09-25 01:54:45 -0700526
tylerliu4140fe82021-01-27 15:45:44 -0800527 auto interest = state.genRevokeInterest(issuedCert);
tylerliu182bc532020-09-25 01:54:45 -0700528
529 int count = 0;
Zhiyi Zhang46049832020-09-28 17:08:12 -0700530 face.onSendData.connect([&](const Data& response) {
tylerliu182bc532020-09-25 01:54:45 -0700531 count++;
532 BOOST_CHECK(security::verifySignature(response, cert));
533 auto contentBlock = response.getContent();
534 contentBlock.parse();
535
tylerliu50d679e2020-10-14 14:08:39 -0700536 BOOST_CHECK(readString(contentBlock.get(tlv::EcdhPub)) != "");
537 BOOST_CHECK(readString(contentBlock.get(tlv::Salt)) != "");
538 BOOST_CHECK(readString(contentBlock.get(tlv::RequestId)) != "");
tylerliu182bc532020-09-25 01:54:45 -0700539
540 auto challengeBlockCount = 0;
541 for (auto const& element : contentBlock.elements()) {
tylerliu50d679e2020-10-14 14:08:39 -0700542 if (element.type() == tlv::Challenge) {
Zhiyi Zhang46049832020-09-28 17:08:12 -0700543 challengeBlockCount++;
544 }
tylerliu182bc532020-09-25 01:54:45 -0700545 }
546
547 BOOST_CHECK(challengeBlockCount != 0);
548
tylerliu4140fe82021-01-27 15:45:44 -0800549 auto challengeList = state.onNewRenewRevokeResponse(response);
Zhiyi Zhangc9ada1b2020-10-29 19:13:15 -0700550 RequestId requestId;
Zhiyi Zhang8fdb36b2020-10-18 11:58:51 -0700551 std::memcpy(requestId.data(), contentBlock.get(tlv::RequestId).value(), contentBlock.get(tlv::RequestId).value_size());
tylerliu7b9185c2020-11-24 12:15:18 -0800552 auto ca_encryption_key = ca.getCaStorage()->getRequest(requestId).encryptionKey;
tylerliuf2e6bb52020-12-13 13:23:05 -0800553 BOOST_CHECK_EQUAL_COLLECTIONS(state.aesKey.begin(), state.aesKey.end(),
Zhiyi Zhang1f9551b2020-10-30 10:30:43 -0700554 ca_encryption_key.begin(), ca_encryption_key.end());
tylerliu182bc532020-09-25 01:54:45 -0700555 });
556 face.receive(*interest);
557
558 advanceClocks(time::milliseconds(20), 60);
559 BOOST_CHECK_EQUAL(count, 1);
560}
561
562BOOST_AUTO_TEST_CASE(HandleRevokeWithBadCert)
563{
564 auto identity = addIdentity(Name("/ndn"));
565 auto key = identity.getDefaultKey();
566 auto cert = key.getDefaultCertificate();
567
Zhiyi Zhang46049832020-09-28 17:08:12 -0700568 util::DummyClientFace face(io, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700569 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
tylerliu182bc532020-09-25 01:54:45 -0700570 advanceClocks(time::milliseconds(20), 60);
571
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700572 // generate a certificate
tylerliu182bc532020-09-25 01:54:45 -0700573 auto clientIdentity = m_keyChain.createIdentity("/ndn/qwerty");
574 auto clientKey = clientIdentity.getDefaultKey();
tylerliua7bea662020-10-08 18:51:02 -0700575 security::Certificate clientCert;
tylerliu182bc532020-09-25 01:54:45 -0700576 clientCert.setName(Name(clientKey.getName()).append("NDNCERT").append(std::to_string(1473283247810732701)));
Zhiyi Zhang8f1ade32020-10-14 16:42:57 -0700577 clientCert.setContentType(ndn::tlv::ContentType_Key);
tylerliu182bc532020-09-25 01:54:45 -0700578 clientCert.setFreshnessPeriod(time::hours(24));
579 clientCert.setContent(clientKey.getPublicKey().data(), clientKey.getPublicKey().size());
580 SignatureInfo signatureInfo;
581 signatureInfo.setValidityPeriod(security::ValidityPeriod(time::system_clock::now(),
Zhiyi Zhang46049832020-09-28 17:08:12 -0700582 time::system_clock::now() + time::hours(10)));
tylerliu182bc532020-09-25 01:54:45 -0700583 m_keyChain.sign(clientCert, signingByKey(clientKey.getName()).setSignatureInfo(signatureInfo));
584
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700585 CaProfile item;
Zhiyi Zhang44c6a352020-12-14 10:57:17 -0800586 item.caPrefix = Name("/ndn");
587 item.cert = std::make_shared<security::Certificate>(cert);
tylerliu4140fe82021-01-27 15:45:44 -0800588 requester::Request state(m_keyChain, item, RequestType::NEW);
tylerliu182bc532020-09-25 01:54:45 -0700589
tylerliu4140fe82021-01-27 15:45:44 -0800590 auto interest = state.genRevokeInterest(clientCert);
tylerliu182bc532020-09-25 01:54:45 -0700591
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700592 bool receiveData = false;
Zhiyi Zhang46049832020-09-28 17:08:12 -0700593 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700594 receiveData = true;
595 auto contentTlv = response.getContent();
596 contentTlv.parse();
tylerliu50d679e2020-10-14 14:08:39 -0700597 BOOST_CHECK(static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv::ErrorCode))) != ErrorCode::NO_ERROR);
tylerliu182bc532020-09-25 01:54:45 -0700598 });
599 face.receive(*interest);
600
601 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700602 BOOST_CHECK_EQUAL(receiveData, true);
tylerliu182bc532020-09-25 01:54:45 -0700603}
604
Zhiyi Zhang46049832020-09-28 17:08:12 -0700605BOOST_AUTO_TEST_SUITE_END() // TestCaModule
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800606
Zhiyi Zhange4891b72020-10-10 15:11:57 -0700607} // namespace tests
608} // namespace ndncert
609} // namespace ndn