blob: 97727c0de1f7d06cb7f11be44df8924a6f670dbf [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 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");
41 BOOST_CHECK_EQUAL(ca.getCaConf().m_caItem.m_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{
50 auto identity = addIdentity(Name("/ndn"));
51 auto key = identity.getDefaultKey();
52 auto cert = key.getDefaultCertificate();
53
Zhiyi Zhang22998612020-09-25 14:43:23 -070054 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -070055 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070056 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangcd57da82020-10-08 20:35:40 -070057 auto profileData = ca.getCaProfileData();
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070058
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070059 Interest interest = MetadataObject::makeDiscoveryInterest(Name("/ndn/CA/INFO"));
60 shared_ptr<Interest> infoInterest = nullptr;
61
Zhiyi Zhang696cd042020-10-07 21:27:36 -070062 face.setInterestFilter(
63 InterestFilter("/ndn/CA/INFO"),
64 [&](const auto&, const Interest& interest) {
Zhiyi Zhangcd57da82020-10-08 20:35:40 -070065 if (interest.getName() == profileData.getName()) {
66 face.put(profileData);
67 }
68 },
69 nullptr, nullptr);
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070070 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070071
72 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -070073 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070074 if (count == 0) {
75 count++;
76 auto block = response.getContent();
77 block.parse();
Zhiyi Zhang8f1ade32020-10-14 16:42:57 -070078 infoInterest =std::make_shared<Interest>(Name(block.get(ndn::tlv::Name)).appendSegment(0));
Zhiyi Zhangcd57da82020-10-08 20:35:40 -070079 infoInterest->setCanBePrefix(false);
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070080 }
81 else {
82 count++;
83 BOOST_CHECK(security::verifySignature(response, cert));
84 auto contentBlock = response.getContent();
85 contentBlock.parse();
Zhiyi Zhang8f1ade32020-10-14 16:42:57 -070086 auto caItem = InfoEncoder::decodeDataContent(contentBlock);
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070087 BOOST_CHECK_EQUAL(caItem.m_caPrefix, "/ndn");
88 BOOST_CHECK_EQUAL(caItem.m_probeParameterKeys.size(), 1);
89 BOOST_CHECK_EQUAL(caItem.m_probeParameterKeys.front(), "full name");
90 BOOST_CHECK_EQUAL(caItem.m_cert->wireEncode(), cert.wireEncode());
91 BOOST_CHECK_EQUAL(caItem.m_caInfo, "ndn testbed ca");
92 }
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -070093 });
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080094 face.receive(interest);
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080095 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070096 face.receive(*infoInterest);
97 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangcd57da82020-10-08 20:35:40 -070098
Zhiyi Zhangfbcab842020-10-07 15:17:13 -070099 BOOST_CHECK_EQUAL(count, 2);
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800100}
101
Zhiyi Zhang6f395812020-09-29 14:42:03 -0700102BOOST_AUTO_TEST_CASE(HandleProbe)
103{
104 auto identity = addIdentity(Name("/ndn"));
105 auto key = identity.getDefaultKey();
106 auto cert = key.getDefaultCertificate();
107
108 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700109 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhang6f395812020-09-29 14:42:03 -0700110 advanceClocks(time::milliseconds(20), 60);
111
112 Interest interest("/ndn/CA/PROBE");
113 interest.setCanBePrefix(false);
114
Zhiyi Zhang8f1ade32020-10-14 16:42:57 -0700115 Block paramTLV = makeEmptyBlock(ndn::tlv::ApplicationParameters);
tylerliu50d679e2020-10-14 14:08:39 -0700116 paramTLV.push_back(makeStringBlock(tlv::ParameterKey, "name"));
117 paramTLV.push_back(makeStringBlock(tlv::ParameterValue, "zhiyi"));
Zhiyi Zhang6f395812020-09-29 14:42:03 -0700118 paramTLV.encode();
119
120 interest.setApplicationParameters(paramTLV);
121
122 int count = 0;
123 face.onSendData.connect([&](const Data& response) {
124 count++;
125 BOOST_CHECK(security::verifySignature(response, cert));
126 Block contentBlock = response.getContent();
127 contentBlock.parse();
tylerliu50d679e2020-10-14 14:08:39 -0700128 Block probeResponse = contentBlock.get(tlv::ProbeResponse);
Zhiyi Zhang6f395812020-09-29 14:42:03 -0700129 probeResponse.parse();
130 Name caName;
Zhiyi Zhang8f1ade32020-10-14 16:42:57 -0700131 caName.wireDecode(probeResponse.get(ndn::tlv::Name));
Zhiyi Zhang8683ec92020-10-07 18:18:35 -0700132 BOOST_CHECK_EQUAL(caName.size(), 2);
Zhiyi Zhang6f395812020-09-29 14:42:03 -0700133 });
134 face.receive(interest);
135
136 advanceClocks(time::milliseconds(20), 60);
137 BOOST_CHECK_EQUAL(count, 1);
138}
139
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700140BOOST_AUTO_TEST_CASE(HandleProbeUsingDefaultHandler)
141{
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700142 auto identity = addIdentity(Name("/ndn"));
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700143 auto key = identity.getDefaultKey();
144 auto cert = key.getDefaultCertificate();
145
Zhiyi Zhang22998612020-09-25 14:43:23 -0700146 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700147 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700148 advanceClocks(time::milliseconds(20), 60);
149
swa770de007bc2020-03-24 21:26:21 -0700150 Interest interest("/ndn/CA/PROBE");
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700151 interest.setCanBePrefix(false);
Suyong Won7968f7a2020-05-12 01:01:25 -0700152
Zhiyi Zhang8f1ade32020-10-14 16:42:57 -0700153 Block paramTLV = makeEmptyBlock(ndn::tlv::ApplicationParameters);
tylerliu50d679e2020-10-14 14:08:39 -0700154 paramTLV.push_back(makeStringBlock(tlv::ParameterKey, "name"));
155 paramTLV.push_back(makeStringBlock(tlv::ParameterValue, "zhiyi"));
Suyong Won7968f7a2020-05-12 01:01:25 -0700156 paramTLV.encode();
157
158 interest.setApplicationParameters(paramTLV);
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700159
160 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700161 face.onSendData.connect([&](const Data& response) {
162 count++;
163 BOOST_CHECK(security::verifySignature(response, cert));
164 auto contentBlock = response.getContent();
165 contentBlock.parse();
tylerliu50d679e2020-10-14 14:08:39 -0700166 auto probeResponseBlock = contentBlock.get(tlv::ProbeResponse);
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700167 probeResponseBlock.parse();
168 Name caPrefix;
Zhiyi Zhang8f1ade32020-10-14 16:42:57 -0700169 caPrefix.wireDecode(probeResponseBlock.get(ndn::tlv::Name));
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700170 BOOST_CHECK(caPrefix != "");
171 });
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700172 face.receive(interest);
173
174 advanceClocks(time::milliseconds(20), 60);
175 BOOST_CHECK_EQUAL(count, 1);
176}
177
Suyong Wone2afeb52020-10-04 03:05:39 +0900178BOOST_AUTO_TEST_CASE(HandleProbeRedirection)
179{
180 auto identity = addIdentity(Name("/ndn"));
181 auto key = identity.getDefaultKey();
182 auto cert = key.getDefaultCertificate();
183
184 util::DummyClientFace face(io, m_keyChain, {true, true});
185 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-5", "ca-storage-memory");
Suyong Wone2afeb52020-10-04 03:05:39 +0900186 advanceClocks(time::milliseconds(20), 60);
187
188 Interest interest("/ndn/CA/PROBE");
189 interest.setCanBePrefix(false);
190
Zhiyi Zhang8f1ade32020-10-14 16:42:57 -0700191 Block paramTLV = makeEmptyBlock(ndn::tlv::ApplicationParameters);
tylerliu50d679e2020-10-14 14:08:39 -0700192 paramTLV.push_back(makeStringBlock(tlv::ParameterKey, "name"));
193 paramTLV.push_back(makeStringBlock(tlv::ParameterValue, "zhiyi"));
Suyong Wone2afeb52020-10-04 03:05:39 +0900194 paramTLV.encode();
195
196 interest.setApplicationParameters(paramTLV);
197
198 int count = 0;
199 face.onSendData.connect([&](const Data& response) {
200 count++;
201 BOOST_CHECK(security::verifySignature(response, cert));
202 Block contentBlock = response.getContent();
203 contentBlock.parse();
204
205 // Test CA sent redirections
Zhiyi Zhang34a8d432020-10-03 22:14:25 -0700206 std::vector<Name> redirectionItems;
207 for (auto item : contentBlock.elements()) {
tylerliu50d679e2020-10-14 14:08:39 -0700208 if (item.type() == tlv::ProbeRedirect) {
Zhiyi Zhang34a8d432020-10-03 22:14:25 -0700209 redirectionItems.push_back(Name(item.blockFromValue()));
210 }
Suyong Wone2afeb52020-10-04 03:05:39 +0900211 }
Zhiyi Zhang34a8d432020-10-03 22:14:25 -0700212 BOOST_CHECK_EQUAL(redirectionItems.size(), 2);
tylerliua7bea662020-10-08 18:51:02 -0700213 BOOST_CHECK_EQUAL(security::extractIdentityFromCertName(redirectionItems[0].getPrefix(-1)), "/ndn/site1");
214 BOOST_CHECK_EQUAL(security::extractIdentityFromCertName(redirectionItems[1].getPrefix(-1)), "/ndn/site1");
Suyong Wone2afeb52020-10-04 03:05:39 +0900215 });
216 face.receive(interest);
217 advanceClocks(time::milliseconds(20), 60);
218 BOOST_CHECK_EQUAL(count, 1);
219}
220
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800221BOOST_AUTO_TEST_CASE(HandleNew)
222{
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700223 auto identity = addIdentity(Name("/ndn"));
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800224 auto key = identity.getDefaultKey();
225 auto cert = key.getDefaultCertificate();
226
Zhiyi Zhang22998612020-09-25 14:43:23 -0700227 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700228 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800229 advanceClocks(time::milliseconds(20), 60);
230
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700231 CaProfile item;
Suyong Won256c9062020-05-11 02:45:56 -0700232 item.m_caPrefix = Name("/ndn");
tylerliua7bea662020-10-08 18:51:02 -0700233 item.m_cert = std::make_shared<security::Certificate>(cert);
Zhiyi Zhang59a366d2020-10-29 19:01:53 -0700234 requester::RequestContext state(m_keyChain, item, RequestType::NEW);
Zhiyi Zhang3002e6b2020-10-29 18:54:07 -0700235 auto interest = requester::Requester::genNewInterest(state, Name("/ndn/zhiyi"),
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700236 time::system_clock::now(),
237 time::system_clock::now() + time::days(1));
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800238
239 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700240 face.onSendData.connect([&](const Data& response) {
241 count++;
242 BOOST_CHECK(security::verifySignature(response, cert));
243 auto contentBlock = response.getContent();
244 contentBlock.parse();
Suyong Won7968f7a2020-05-12 01:01:25 -0700245
tylerliu50d679e2020-10-14 14:08:39 -0700246 BOOST_CHECK(readString(contentBlock.get(tlv::EcdhPub)) != "");
247 BOOST_CHECK(readString(contentBlock.get(tlv::Salt)) != "");
248 BOOST_CHECK(readString(contentBlock.get(tlv::RequestId)) != "");
Suyong Won7968f7a2020-05-12 01:01:25 -0700249
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700250 auto challengeBlockCount = 0;
251 for (auto const& element : contentBlock.elements()) {
tylerliu50d679e2020-10-14 14:08:39 -0700252 if (element.type() == tlv::Challenge) {
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700253 challengeBlockCount++;
Suyong Won7968f7a2020-05-12 01:01:25 -0700254 }
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700255 }
Suyong Won7968f7a2020-05-12 01:01:25 -0700256
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700257 BOOST_CHECK(challengeBlockCount != 0);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700258
Zhiyi Zhang3002e6b2020-10-29 18:54:07 -0700259 auto challengeList = requester::Requester::onNewRenewRevokeResponse(state, response);
Zhiyi Zhangc9ada1b2020-10-29 19:13:15 -0700260 RequestId requestId;
Zhiyi Zhang8fdb36b2020-10-18 11:58:51 -0700261 std::memcpy(requestId.data(), contentBlock.get(tlv::RequestId).value(), contentBlock.get(tlv::RequestId).value_size());
262 auto ca_encryption_key = ca.getCaStorage()->getRequest(requestId).m_encryptionKey;
Zhiyi Zhang1f9551b2020-10-30 10:30:43 -0700263 BOOST_CHECK_EQUAL_COLLECTIONS(state.m_aesKey.begin(), state.m_aesKey.end(),
264 ca_encryption_key.begin(), ca_encryption_key.end());
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700265 });
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700266 face.receive(*interest);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800267
268 advanceClocks(time::milliseconds(20), 60);
269 BOOST_CHECK_EQUAL(count, 1);
270}
271
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700272BOOST_AUTO_TEST_CASE(HandleNewWithInvalidValidityPeriod1)
273{
274 auto identity = addIdentity(Name("/ndn"));
275 auto key = identity.getDefaultKey();
276 auto cert = key.getDefaultCertificate();
277
Zhiyi Zhang22998612020-09-25 14:43:23 -0700278 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700279 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1");
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700280 advanceClocks(time::milliseconds(20), 60);
281
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700282 CaProfile item;
Suyong Won256c9062020-05-11 02:45:56 -0700283 item.m_caPrefix = Name("/ndn");
tylerliua7bea662020-10-08 18:51:02 -0700284 item.m_cert = std::make_shared<security::Certificate>(cert);
Zhiyi Zhang59a366d2020-10-29 19:01:53 -0700285 requester::RequestContext state(m_keyChain, item, RequestType::NEW);
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700286 auto current_tp = time::system_clock::now();
Zhiyi Zhang3002e6b2020-10-29 18:54:07 -0700287 auto interest1 = requester::Requester::genNewInterest(state, Name("/ndn/zhiyi"), current_tp, current_tp - time::hours(1));
288 auto interest2 = requester::Requester::genNewInterest(state, Name("/ndn/zhiyi"), current_tp, current_tp + time::days(361));
289 auto interest3 = requester::Requester::genNewInterest(state, Name("/ndn/zhiyi"), current_tp - time::hours(1), current_tp + time::hours(2));
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700290 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700291 auto contentTlv = response.getContent();
292 contentTlv.parse();
tylerliu50d679e2020-10-14 14:08:39 -0700293 auto errorCode = static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv::ErrorCode)));
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700294 BOOST_CHECK(errorCode != ErrorCode::NO_ERROR);
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700295 });
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700296 face.receive(*interest1);
297 face.receive(*interest2);
298 face.receive(*interest3);
299
300 advanceClocks(time::milliseconds(20), 60);
301}
302
tylerliu0b6d0db2020-09-28 17:52:02 -0700303BOOST_AUTO_TEST_CASE(HandleNewWithLongSuffix)
304{
305 auto identity = addIdentity(Name("/ndn"));
306 auto key = identity.getDefaultKey();
307 auto cert = key.getDefaultCertificate();
308
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700309 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700310 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
tylerliu0b6d0db2020-09-28 17:52:02 -0700311 advanceClocks(time::milliseconds(20), 60);
312
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700313 CaProfile item;
tylerliu0b6d0db2020-09-28 17:52:02 -0700314 item.m_caPrefix = Name("/ndn");
tylerliua7bea662020-10-08 18:51:02 -0700315 item.m_cert = std::make_shared<security::Certificate>(cert);
Zhiyi Zhang59a366d2020-10-29 19:01:53 -0700316 requester::RequestContext state(m_keyChain, item, RequestType::NEW);
tylerliu0b6d0db2020-09-28 17:52:02 -0700317
Zhiyi Zhang3002e6b2020-10-29 18:54:07 -0700318 auto interest1 = requester::Requester::genNewInterest(state, Name("/ndn/a"), time::system_clock::now(),
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700319 time::system_clock::now() + time::days(1));
Zhiyi Zhang3002e6b2020-10-29 18:54:07 -0700320 auto interest2 = requester::Requester::genNewInterest(state, Name("/ndn/a/b"), time::system_clock::now(),
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700321 time::system_clock::now() + time::days(1));
Zhiyi Zhang3002e6b2020-10-29 18:54:07 -0700322 auto interest3 = requester::Requester::genNewInterest(state, Name("/ndn/a/b/c/d"), time::system_clock::now(),
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700323 time::system_clock::now() + time::days(1));
tylerliu0b6d0db2020-09-28 17:52:02 -0700324
tylerliu0b6d0db2020-09-28 17:52:02 -0700325 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700326 auto contentTlv = response.getContent();
327 contentTlv.parse();
328 if (interest3->getName().isPrefixOf(response.getName())) {
tylerliu50d679e2020-10-14 14:08:39 -0700329 auto errorCode = static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv::ErrorCode)));
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700330 BOOST_CHECK(errorCode != ErrorCode::NO_ERROR);
331 }
332 else {
333 // should successfully get responses
tylerliu50d679e2020-10-14 14:08:39 -0700334 BOOST_CHECK_EXCEPTION(readNonNegativeInteger(contentTlv.get(tlv::ErrorCode)), std::runtime_error,
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700335 [](const auto& e) { return true; });
336 }
tylerliu0b6d0db2020-09-28 17:52:02 -0700337 });
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700338 face.receive(*interest1);
339 face.receive(*interest2);
340 face.receive(*interest3);
tylerliu0b6d0db2020-09-28 17:52:02 -0700341 advanceClocks(time::milliseconds(20), 60);
tylerliu0b6d0db2020-09-28 17:52:02 -0700342}
343
tylerliu0b6d0db2020-09-28 17:52:02 -0700344BOOST_AUTO_TEST_CASE(HandleNewWithInvalidLength1)
345{
346 auto identity = addIdentity(Name("/ndn"));
347 auto key = identity.getDefaultKey();
348 auto cert = key.getDefaultCertificate();
349
350 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700351 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1");
tylerliu0b6d0db2020-09-28 17:52:02 -0700352 advanceClocks(time::milliseconds(20), 60);
353
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700354 CaProfile item;
tylerliu0b6d0db2020-09-28 17:52:02 -0700355 item.m_caPrefix = Name("/ndn");
tylerliua7bea662020-10-08 18:51:02 -0700356 item.m_cert = std::make_shared<security::Certificate>(cert);
Zhiyi Zhang59a366d2020-10-29 19:01:53 -0700357 requester::RequestContext state(m_keyChain, item, RequestType::NEW);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700358
tylerliu0b6d0db2020-09-28 17:52:02 -0700359 auto current_tp = time::system_clock::now();
Zhiyi Zhang3002e6b2020-10-29 18:54:07 -0700360 auto interest1 = requester::Requester::genNewInterest(state, Name("/ndn"), current_tp, current_tp + time::days(1));
361 auto interest2 = requester::Requester::genNewInterest(state, Name("/ndn/a/b/c/d"), current_tp, current_tp + time::days(1));
tylerliu0b6d0db2020-09-28 17:52:02 -0700362 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700363 auto contentTlv = response.getContent();
364 contentTlv.parse();
tylerliu50d679e2020-10-14 14:08:39 -0700365 auto errorCode = static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv::ErrorCode)));
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700366 BOOST_CHECK(errorCode != ErrorCode::NO_ERROR);
tylerliu0b6d0db2020-09-28 17:52:02 -0700367 });
368 face.receive(*interest1);
369 face.receive(*interest2);
370
371 advanceClocks(time::milliseconds(20), 60);
372}
373
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700374BOOST_AUTO_TEST_CASE(HandleChallenge)
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800375{
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700376 auto identity = addIdentity(Name("/ndn"));
377 auto key = identity.getDefaultKey();
378 auto cert = key.getDefaultCertificate();
379
Zhiyi Zhang22998612020-09-25 14:43:23 -0700380 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700381 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800382 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700383
384 // generate NEW Interest
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700385 CaProfile item;
Suyong Won256c9062020-05-11 02:45:56 -0700386 item.m_caPrefix = Name("/ndn");
tylerliua7bea662020-10-08 18:51:02 -0700387 item.m_cert = std::make_shared<security::Certificate>(cert);
Zhiyi Zhang59a366d2020-10-29 19:01:53 -0700388 requester::RequestContext state(m_keyChain, item, RequestType::NEW);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700389
Zhiyi Zhang3002e6b2020-10-29 18:54:07 -0700390 auto newInterest = requester::Requester::genNewInterest(state, Name("/ndn/zhiyi"), time::system_clock::now(),
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700391 time::system_clock::now() + time::days(1));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700392
393 // generate CHALLENGE Interest
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700394 shared_ptr<Interest> challengeInterest = nullptr;
395 shared_ptr<Interest> challengeInterest2 = nullptr;
396 shared_ptr<Interest> challengeInterest3 = nullptr;
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800397
398 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700399 face.onSendData.connect([&](const Data& response) {
swa770de007bc2020-03-24 21:26:21 -0700400 if (Name("/ndn/CA/NEW").isPrefixOf(response.getName())) {
Zhiyi Zhang3002e6b2020-10-29 18:54:07 -0700401 auto challengeList = requester::Requester::onNewRenewRevokeResponse(state, response);
402 auto paramList = requester::Requester::selectOrContinueChallenge(state, "pin");
403 challengeInterest = requester::Requester::genChallengeInterest(state, std::move(paramList));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700404 }
swa770de007bc2020-03-24 21:26:21 -0700405 else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 0) {
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800406 count++;
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700407 BOOST_CHECK(security::verifySignature(response, cert));
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800408
Zhiyi Zhang3002e6b2020-10-29 18:54:07 -0700409 requester::Requester::onChallengeResponse(state, response);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700410 BOOST_CHECK(state.m_status == Status::CHALLENGE);
411 BOOST_CHECK_EQUAL(state.m_challengeStatus, ChallengePin::NEED_CODE);
Zhiyi Zhang3002e6b2020-10-29 18:54:07 -0700412 auto paramList = requester::Requester::selectOrContinueChallenge(state, "pin");
413 challengeInterest2 = requester::Requester::genChallengeInterest(state, std::move(paramList));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700414 }
swa770de007bc2020-03-24 21:26:21 -0700415 else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 1) {
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700416 count++;
417 BOOST_CHECK(security::verifySignature(response, cert));
418
Zhiyi Zhang3002e6b2020-10-29 18:54:07 -0700419 requester::Requester::onChallengeResponse(state, response);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700420 BOOST_CHECK(state.m_status == Status::CHALLENGE);
421 BOOST_CHECK_EQUAL(state.m_challengeStatus, ChallengePin::WRONG_CODE);
Davide Pesavento914d05f2019-07-13 16:20:19 -0400422
Zhiyi Zhang3002e6b2020-10-29 18:54:07 -0700423 auto paramList = requester::Requester::selectOrContinueChallenge(state, "pin");
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700424 auto request = ca.getCertificateRequest(*challengeInterest2);
Zhiyi Zhang8fdb36b2020-10-18 11:58:51 -0700425 auto secret = request->m_challengeState->m_secrets.get(ChallengePin::PARAMETER_KEY_CODE, "");
Zhiyi Zhang46049832020-09-28 17:08:12 -0700426 std::get<1>(paramList[0]) = secret;
Zhiyi Zhang3002e6b2020-10-29 18:54:07 -0700427 challengeInterest3 = requester::Requester::genChallengeInterest(state, std::move(paramList));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700428 }
swa770de007bc2020-03-24 21:26:21 -0700429 else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 2) {
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700430 count++;
431 BOOST_CHECK(security::verifySignature(response, cert));
Zhiyi Zhang3002e6b2020-10-29 18:54:07 -0700432 requester::Requester::onChallengeResponse(state, response);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700433 BOOST_CHECK(state.m_status == Status::SUCCESS);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700434 }
Davide Pesavento914d05f2019-07-13 16:20:19 -0400435 });
436
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700437 face.receive(*newInterest);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800438 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700439 face.receive(*challengeInterest);
440 advanceClocks(time::milliseconds(20), 60);
441 face.receive(*challengeInterest2);
442 advanceClocks(time::milliseconds(20), 60);
443 face.receive(*challengeInterest3);
444 advanceClocks(time::milliseconds(20), 60);
445 BOOST_CHECK_EQUAL(count, 3);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800446}
447
tylerliu182bc532020-09-25 01:54:45 -0700448BOOST_AUTO_TEST_CASE(HandleRevoke)
449{
450 auto identity = addIdentity(Name("/ndn"));
451 auto key = identity.getDefaultKey();
452 auto cert = key.getDefaultCertificate();
453
Zhiyi Zhang46049832020-09-28 17:08:12 -0700454 util::DummyClientFace face(io, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700455 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
tylerliu182bc532020-09-25 01:54:45 -0700456 advanceClocks(time::milliseconds(20), 60);
457
458 //generate a certificate
459 auto clientIdentity = m_keyChain.createIdentity("/ndn/qwerty");
460 auto clientKey = clientIdentity.getDefaultKey();
tylerliua7bea662020-10-08 18:51:02 -0700461 security::Certificate clientCert;
tylerliu182bc532020-09-25 01:54:45 -0700462 clientCert.setName(Name(clientKey.getName()).append("cert-request").appendVersion());
Zhiyi Zhang8f1ade32020-10-14 16:42:57 -0700463 clientCert.setContentType(ndn::tlv::ContentType_Key);
tylerliu182bc532020-09-25 01:54:45 -0700464 clientCert.setFreshnessPeriod(time::hours(24));
465 clientCert.setContent(clientKey.getPublicKey().data(), clientKey.getPublicKey().size());
466 SignatureInfo signatureInfo;
467 signatureInfo.setValidityPeriod(security::ValidityPeriod(time::system_clock::now(),
Zhiyi Zhang46049832020-09-28 17:08:12 -0700468 time::system_clock::now() + time::hours(10)));
tylerliu182bc532020-09-25 01:54:45 -0700469 m_keyChain.sign(clientCert, signingByKey(clientKey.getName()).setSignatureInfo(signatureInfo));
Zhiyi Zhangc9ada1b2020-10-29 19:13:15 -0700470 RequestId requestId = {1,2,3,4,5,6,7,8};
Zhiyi Zhang1f9551b2020-10-30 10:30:43 -0700471 std::array<uint8_t, 16> aesKey;
472 RequestState certRequest(Name("/ndn"), requestId, RequestType::NEW, Status::SUCCESS, clientCert, std::move(aesKey));
tylerliu182bc532020-09-25 01:54:45 -0700473 auto issuedCert = ca.issueCertificate(certRequest);
474
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700475 CaProfile item;
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700476 item.m_caPrefix = Name("/ndn");
tylerliua7bea662020-10-08 18:51:02 -0700477 item.m_cert = std::make_shared<security::Certificate>(cert);
Zhiyi Zhang59a366d2020-10-29 19:01:53 -0700478 requester::RequestContext state(m_keyChain, item, RequestType::REVOKE);
tylerliu182bc532020-09-25 01:54:45 -0700479
Zhiyi Zhang3002e6b2020-10-29 18:54:07 -0700480 auto interest = requester::Requester::genRevokeInterest(state, issuedCert);
tylerliu182bc532020-09-25 01:54:45 -0700481
482 int count = 0;
Zhiyi Zhang46049832020-09-28 17:08:12 -0700483 face.onSendData.connect([&](const Data& response) {
tylerliu182bc532020-09-25 01:54:45 -0700484 count++;
485 BOOST_CHECK(security::verifySignature(response, cert));
486 auto contentBlock = response.getContent();
487 contentBlock.parse();
488
tylerliu50d679e2020-10-14 14:08:39 -0700489 BOOST_CHECK(readString(contentBlock.get(tlv::EcdhPub)) != "");
490 BOOST_CHECK(readString(contentBlock.get(tlv::Salt)) != "");
491 BOOST_CHECK(readString(contentBlock.get(tlv::RequestId)) != "");
tylerliu182bc532020-09-25 01:54:45 -0700492
493 auto challengeBlockCount = 0;
494 for (auto const& element : contentBlock.elements()) {
tylerliu50d679e2020-10-14 14:08:39 -0700495 if (element.type() == tlv::Challenge) {
Zhiyi Zhang46049832020-09-28 17:08:12 -0700496 challengeBlockCount++;
497 }
tylerliu182bc532020-09-25 01:54:45 -0700498 }
499
500 BOOST_CHECK(challengeBlockCount != 0);
501
Zhiyi Zhang3002e6b2020-10-29 18:54:07 -0700502 auto challengeList = requester::Requester::onNewRenewRevokeResponse(state, response);
Zhiyi Zhangc9ada1b2020-10-29 19:13:15 -0700503 RequestId requestId;
Zhiyi Zhang8fdb36b2020-10-18 11:58:51 -0700504 std::memcpy(requestId.data(), contentBlock.get(tlv::RequestId).value(), contentBlock.get(tlv::RequestId).value_size());
505 auto ca_encryption_key = ca.getCaStorage()->getRequest(requestId).m_encryptionKey;
Zhiyi Zhang1f9551b2020-10-30 10:30:43 -0700506 BOOST_CHECK_EQUAL_COLLECTIONS(state.m_aesKey.begin(), state.m_aesKey.end(),
507 ca_encryption_key.begin(), ca_encryption_key.end());
tylerliu182bc532020-09-25 01:54:45 -0700508 });
509 face.receive(*interest);
510
511 advanceClocks(time::milliseconds(20), 60);
512 BOOST_CHECK_EQUAL(count, 1);
513}
514
515BOOST_AUTO_TEST_CASE(HandleRevokeWithBadCert)
516{
517 auto identity = addIdentity(Name("/ndn"));
518 auto key = identity.getDefaultKey();
519 auto cert = key.getDefaultCertificate();
520
Zhiyi Zhang46049832020-09-28 17:08:12 -0700521 util::DummyClientFace face(io, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700522 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
tylerliu182bc532020-09-25 01:54:45 -0700523 advanceClocks(time::milliseconds(20), 60);
524
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700525 // generate a certificate
tylerliu182bc532020-09-25 01:54:45 -0700526 auto clientIdentity = m_keyChain.createIdentity("/ndn/qwerty");
527 auto clientKey = clientIdentity.getDefaultKey();
tylerliua7bea662020-10-08 18:51:02 -0700528 security::Certificate clientCert;
tylerliu182bc532020-09-25 01:54:45 -0700529 clientCert.setName(Name(clientKey.getName()).append("NDNCERT").append(std::to_string(1473283247810732701)));
Zhiyi Zhang8f1ade32020-10-14 16:42:57 -0700530 clientCert.setContentType(ndn::tlv::ContentType_Key);
tylerliu182bc532020-09-25 01:54:45 -0700531 clientCert.setFreshnessPeriod(time::hours(24));
532 clientCert.setContent(clientKey.getPublicKey().data(), clientKey.getPublicKey().size());
533 SignatureInfo signatureInfo;
534 signatureInfo.setValidityPeriod(security::ValidityPeriod(time::system_clock::now(),
Zhiyi Zhang46049832020-09-28 17:08:12 -0700535 time::system_clock::now() + time::hours(10)));
tylerliu182bc532020-09-25 01:54:45 -0700536 m_keyChain.sign(clientCert, signingByKey(clientKey.getName()).setSignatureInfo(signatureInfo));
537
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700538 CaProfile item;
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700539 item.m_caPrefix = Name("/ndn");
tylerliua7bea662020-10-08 18:51:02 -0700540 item.m_cert = std::make_shared<security::Certificate>(cert);
Zhiyi Zhang59a366d2020-10-29 19:01:53 -0700541 requester::RequestContext state(m_keyChain, item, RequestType::NEW);
tylerliu182bc532020-09-25 01:54:45 -0700542
Zhiyi Zhang3002e6b2020-10-29 18:54:07 -0700543 auto interest = requester::Requester::genRevokeInterest(state, clientCert);
tylerliu182bc532020-09-25 01:54:45 -0700544
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700545 bool receiveData = false;
Zhiyi Zhang46049832020-09-28 17:08:12 -0700546 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700547 receiveData = true;
548 auto contentTlv = response.getContent();
549 contentTlv.parse();
tylerliu50d679e2020-10-14 14:08:39 -0700550 BOOST_CHECK(static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv::ErrorCode))) != ErrorCode::NO_ERROR);
tylerliu182bc532020-09-25 01:54:45 -0700551 });
552 face.receive(*interest);
553
554 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700555 BOOST_CHECK_EQUAL(receiveData, true);
tylerliu182bc532020-09-25 01:54:45 -0700556}
557
Zhiyi Zhang46049832020-09-28 17:08:12 -0700558BOOST_AUTO_TEST_SUITE_END() // TestCaModule
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800559
Zhiyi Zhange4891b72020-10-10 15:11:57 -0700560} // namespace tests
561} // namespace ndncert
562} // namespace ndn