blob: 15e48df6f9b16aa422e36e293d796f1d01ceac48 [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 Zhangf5246c42017-01-26 09:39:20 -080022#include "challenge-module.hpp"
Zhiyi Zhang8bd8e5b2020-09-29 17:40:40 -070023#include "challenge-modules/challenge-email.hpp"
24#include "challenge-modules/challenge-pin.hpp"
Suyong Won7968f7a2020-05-12 01:01:25 -070025#include "protocol-detail/info.hpp"
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070026#include "requester.hpp"
Zhiyi Zhang5d80e1e2020-09-25 11:34:54 -070027#include "test-common.hpp"
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080028
29namespace ndn {
30namespace ndncert {
31namespace tests {
32
Zhiyi Zhangae123bf2017-04-14 12:24:53 -070033BOOST_FIXTURE_TEST_SUITE(TestCaModule, DatabaseFixture)
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080034
35BOOST_AUTO_TEST_CASE(Initialization)
36{
Zhiyi Zhang22998612020-09-25 14:43:23 -070037 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -070038 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
39 BOOST_CHECK_EQUAL(ca.getCaConf().m_caItem.m_caPrefix, "/ndn");
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080040
41 auto identity = addIdentity(Name("/ndn/site2"));
42 auto key = identity.getDefaultKey();
43 auto cert = key.getDefaultCertificate();
44 ca.getCaStorage()->addCertificate("111", cert);
45 BOOST_CHECK_EQUAL(ca.getCaStorage()->getCertificate("111").getIdentity(), Name("/ndn/site2"));
46
47 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070048 BOOST_CHECK_EQUAL(ca.m_registeredPrefixHandles.size(), 2);
Zhiyi Zhang46049832020-09-28 17:08:12 -070049 BOOST_CHECK_EQUAL(ca.m_interestFilterHandles.size(), 5); // onInfo, onProbe, onNew, onChallenge, onRevoke
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080050}
51
swa77020643ac2020-03-26 02:24:45 -070052BOOST_AUTO_TEST_CASE(HandleInfo)
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070053{
54 auto identity = addIdentity(Name("/ndn"));
55 auto key = identity.getDefaultKey();
56 auto cert = key.getDefaultCertificate();
57
Zhiyi Zhang22998612020-09-25 14:43:23 -070058 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -070059 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070060 advanceClocks(time::milliseconds(20), 60);
61
swa77020643ac2020-03-26 02:24:45 -070062 Interest interest("/ndn/CA/INFO");
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070063 interest.setCanBePrefix(false);
64
65 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -070066 face.onSendData.connect([&](const Data& response) {
67 count++;
68 BOOST_CHECK(security::verifySignature(response, cert));
69 auto contentBlock = response.getContent();
70 contentBlock.parse();
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -070071 auto caItem = INFO::decodeDataContent(contentBlock);
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -070072 BOOST_CHECK_EQUAL(caItem.m_caPrefix, "/ndn");
Zhiyi Zhangb940aa12020-09-30 16:38:57 -070073 BOOST_CHECK_EQUAL(caItem.m_probeParameterKeys.size(), 1);
Zhiyi Zhang9829da92020-09-30 16:19:34 -070074 BOOST_CHECK_EQUAL(caItem.m_cert->wireEncode(), cert.wireEncode());
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -070075 BOOST_CHECK_EQUAL(caItem.m_caInfo, "ndn testbed ca");
76 });
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080077 face.receive(interest);
78
79 advanceClocks(time::milliseconds(20), 60);
80 BOOST_CHECK_EQUAL(count, 1);
81}
82
Zhiyi Zhang6f395812020-09-29 14:42:03 -070083BOOST_AUTO_TEST_CASE(HandleProbe)
84{
85 auto identity = addIdentity(Name("/ndn"));
86 auto key = identity.getDefaultKey();
87 auto cert = key.getDefaultCertificate();
88
89 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -070090 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhang6f395812020-09-29 14:42:03 -070091 ca.setNameAssignmentFunction([&](const std::vector<std::tuple<std::string, std::string>>) -> std::vector<std::string> {
92 std::vector<std::string> result;
93 result.push_back("example");
94 return result;
95 });
96 advanceClocks(time::milliseconds(20), 60);
97
98 Interest interest("/ndn/CA/PROBE");
99 interest.setCanBePrefix(false);
100
101 Block paramTLV = makeEmptyBlock(tlv::ApplicationParameters);
102 paramTLV.push_back(makeStringBlock(tlv_parameter_key, "name"));
103 paramTLV.push_back(makeStringBlock(tlv_parameter_value, "zhiyi"));
104 paramTLV.encode();
105
106 interest.setApplicationParameters(paramTLV);
107
108 int count = 0;
109 face.onSendData.connect([&](const Data& response) {
110 count++;
111 BOOST_CHECK(security::verifySignature(response, cert));
112 Block contentBlock = response.getContent();
113 contentBlock.parse();
114 Block probeResponse = contentBlock.get(tlv_probe_response);
115 probeResponse.parse();
116 Name caName;
117 caName.wireDecode(probeResponse.get(tlv::Name));
118 BOOST_CHECK_EQUAL(caName, "/ndn/example");
119 });
120 face.receive(interest);
121
122 advanceClocks(time::milliseconds(20), 60);
123 BOOST_CHECK_EQUAL(count, 1);
124}
125
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700126BOOST_AUTO_TEST_CASE(HandleProbeUsingDefaultHandler)
127{
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700128 auto identity = addIdentity(Name("/ndn"));
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700129 auto key = identity.getDefaultKey();
130 auto cert = key.getDefaultCertificate();
131
Zhiyi Zhang22998612020-09-25 14:43:23 -0700132 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700133 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700134 advanceClocks(time::milliseconds(20), 60);
135
swa770de007bc2020-03-24 21:26:21 -0700136 Interest interest("/ndn/CA/PROBE");
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700137 interest.setCanBePrefix(false);
Suyong Won7968f7a2020-05-12 01:01:25 -0700138
139 Block paramTLV = makeEmptyBlock(tlv::ApplicationParameters);
Zhiyi Zhang6f395812020-09-29 14:42:03 -0700140 paramTLV.push_back(makeStringBlock(tlv_parameter_key, "name"));
Suyong Won7968f7a2020-05-12 01:01:25 -0700141 paramTLV.push_back(makeStringBlock(tlv_parameter_value, "zhiyi"));
142 paramTLV.encode();
143
144 interest.setApplicationParameters(paramTLV);
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700145
146 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700147 face.onSendData.connect([&](const Data& response) {
148 count++;
149 BOOST_CHECK(security::verifySignature(response, cert));
150 auto contentBlock = response.getContent();
151 contentBlock.parse();
152 auto probeResponseBlock = contentBlock.get(tlv_probe_response);
153 probeResponseBlock.parse();
154 Name caPrefix;
155 caPrefix.wireDecode(probeResponseBlock.get(tlv::Name));
156 BOOST_CHECK(caPrefix != "");
157 });
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700158 face.receive(interest);
159
160 advanceClocks(time::milliseconds(20), 60);
161 BOOST_CHECK_EQUAL(count, 1);
162}
163
Suyong Wone2afeb52020-10-04 03:05:39 +0900164BOOST_AUTO_TEST_CASE(HandleProbeRedirection)
165{
166 auto identity = addIdentity(Name("/ndn"));
167 auto key = identity.getDefaultKey();
168 auto cert = key.getDefaultCertificate();
169
170 util::DummyClientFace face(io, m_keyChain, {true, true});
171 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-5", "ca-storage-memory");
172 ca.setNameAssignmentFunction([&](const std::vector<std::tuple<std::string, std::string>>) -> std::vector<std::string> {
173 std::vector<std::string> result;
174 result.push_back("example");
175 return result;
176 });
177 advanceClocks(time::milliseconds(20), 60);
178
179 Interest interest("/ndn/CA/PROBE");
180 interest.setCanBePrefix(false);
181
182 Block paramTLV = makeEmptyBlock(tlv::ApplicationParameters);
183 paramTLV.push_back(makeStringBlock(tlv_parameter_key, "name"));
184 paramTLV.push_back(makeStringBlock(tlv_parameter_value, "zhiyi"));
185 paramTLV.encode();
186
187 interest.setApplicationParameters(paramTLV);
188
189 int count = 0;
190 face.onSendData.connect([&](const Data& response) {
191 count++;
192 BOOST_CHECK(security::verifySignature(response, cert));
193 Block contentBlock = response.getContent();
194 contentBlock.parse();
195
196 // Test CA sent redirections
197 BOOST_CHECK_EQUAL(true, contentBlock.get(tlv_probe_redirect).hasValue());
198 Block probeRedirect = contentBlock.get(tlv_probe_redirect);
199 probeRedirect.parse();
200 // Test the case where we have multiple probeRedirects
201 BOOST_CHECK_EQUAL(probeRedirect.elements().size(), 2)
202 for (const auto& item : probeRedirect.elements()) {
203 Name caName;
204 caName.wireDecode(item.get(tlv::Name));
205 // TODO: Checkout the format of the name
206 BOOST_CHECK_EQUAL(caName, "/ndn/example");
207 }
208 });
209 face.receive(interest);
210 advanceClocks(time::milliseconds(20), 60);
211 BOOST_CHECK_EQUAL(count, 1);
212}
213
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800214BOOST_AUTO_TEST_CASE(HandleNew)
215{
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700216 auto identity = addIdentity(Name("/ndn"));
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800217 auto key = identity.getDefaultKey();
218 auto cert = key.getDefaultCertificate();
219
Zhiyi Zhang22998612020-09-25 14:43:23 -0700220 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700221 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800222 advanceClocks(time::milliseconds(20), 60);
223
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700224 CaProfile item;
Suyong Won256c9062020-05-11 02:45:56 -0700225 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700226 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700227 RequesterState state(m_keyChain, item, RequestType::NEW);
228 auto interest = Requester::genNewInterest(state, Name("/ndn/zhiyi"),
229 time::system_clock::now(),
230 time::system_clock::now() + time::days(1));
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800231
232 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700233 face.onSendData.connect([&](const Data& response) {
234 count++;
235 BOOST_CHECK(security::verifySignature(response, cert));
236 auto contentBlock = response.getContent();
237 contentBlock.parse();
Suyong Won7968f7a2020-05-12 01:01:25 -0700238
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700239 BOOST_CHECK(readString(contentBlock.get(tlv_ecdh_pub)) != "");
240 BOOST_CHECK(readString(contentBlock.get(tlv_salt)) != "");
241 BOOST_CHECK(readString(contentBlock.get(tlv_request_id)) != "");
Suyong Won7968f7a2020-05-12 01:01:25 -0700242
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700243 auto challengeBlockCount = 0;
244 for (auto const& element : contentBlock.elements()) {
245 if (element.type() == tlv_challenge) {
246 challengeBlockCount++;
Suyong Won7968f7a2020-05-12 01:01:25 -0700247 }
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700248 }
Suyong Won7968f7a2020-05-12 01:01:25 -0700249
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700250 BOOST_CHECK(challengeBlockCount != 0);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700251
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700252 auto challengeList = Requester::onNewRenewRevokeResponse(state, response);
tylerliu8e170d62020-09-30 01:31:53 -0700253 auto ca_encryption_key = ca.getCaStorage()->getRequest(readString(contentBlock.get(tlv_request_id))).m_encryptionKey;
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700254 BOOST_CHECK_EQUAL_COLLECTIONS(state.m_aesKey, state.m_aesKey + sizeof(state.m_aesKey),
tylerliu8e170d62020-09-30 01:31:53 -0700255 ca_encryption_key.value(), ca_encryption_key.value() + ca_encryption_key.value_size());
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700256 });
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700257 face.receive(*interest);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800258
259 advanceClocks(time::milliseconds(20), 60);
260 BOOST_CHECK_EQUAL(count, 1);
261}
262
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700263BOOST_AUTO_TEST_CASE(HandleNewWithInvalidValidityPeriod1)
264{
265 auto identity = addIdentity(Name("/ndn"));
266 auto key = identity.getDefaultKey();
267 auto cert = key.getDefaultCertificate();
268
Zhiyi Zhang22998612020-09-25 14:43:23 -0700269 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700270 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1");
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700271 advanceClocks(time::milliseconds(20), 60);
272
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700273 CaProfile item;
Suyong Won256c9062020-05-11 02:45:56 -0700274 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700275 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700276 RequesterState state(m_keyChain, item, RequestType::NEW);
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700277 auto current_tp = time::system_clock::now();
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700278 auto interest1 = Requester::genNewInterest(state, Name("/ndn/zhiyi"), current_tp, current_tp - time::hours(1));
279 auto interest2 = Requester::genNewInterest(state, Name("/ndn/zhiyi"), current_tp, current_tp + time::days(361));
280 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 -0700281 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700282 auto contentTlv = response.getContent();
283 contentTlv.parse();
284 auto errorCode = static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv_error_code)));
285 BOOST_CHECK(errorCode != ErrorCode::NO_ERROR);
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700286 });
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700287 face.receive(*interest1);
288 face.receive(*interest2);
289 face.receive(*interest3);
290
291 advanceClocks(time::milliseconds(20), 60);
292}
293
tylerliu0b6d0db2020-09-28 17:52:02 -0700294BOOST_AUTO_TEST_CASE(HandleNewWithLongSuffix)
295{
296 auto identity = addIdentity(Name("/ndn"));
297 auto key = identity.getDefaultKey();
298 auto cert = key.getDefaultCertificate();
299
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700300 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700301 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
tylerliu0b6d0db2020-09-28 17:52:02 -0700302 advanceClocks(time::milliseconds(20), 60);
303
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700304 CaProfile item;
tylerliu0b6d0db2020-09-28 17:52:02 -0700305 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700306 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700307 RequesterState state(m_keyChain, item, RequestType::NEW);
tylerliu0b6d0db2020-09-28 17:52:02 -0700308
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700309 auto interest1 = Requester::genNewInterest(state, Name("/ndn/a"), time::system_clock::now(),
310 time::system_clock::now() + time::days(1));
311 auto interest2 = Requester::genNewInterest(state, Name("/ndn/a/b"), time::system_clock::now(),
312 time::system_clock::now() + time::days(1));
313 auto interest3 = Requester::genNewInterest(state, Name("/ndn/a/b/c/d"), time::system_clock::now(),
314 time::system_clock::now() + time::days(1));
tylerliu0b6d0db2020-09-28 17:52:02 -0700315
tylerliu0b6d0db2020-09-28 17:52:02 -0700316 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700317 auto contentTlv = response.getContent();
318 contentTlv.parse();
319 if (interest3->getName().isPrefixOf(response.getName())) {
320 auto errorCode = static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv_error_code)));
321 BOOST_CHECK(errorCode != ErrorCode::NO_ERROR);
322 }
323 else {
324 // should successfully get responses
325 BOOST_CHECK_EXCEPTION(readNonNegativeInteger(contentTlv.get(tlv_error_code)), std::runtime_error,
326 [](const auto& e) { return true; });
327 }
tylerliu0b6d0db2020-09-28 17:52:02 -0700328 });
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700329 face.receive(*interest1);
330 face.receive(*interest2);
331 face.receive(*interest3);
tylerliu0b6d0db2020-09-28 17:52:02 -0700332 advanceClocks(time::milliseconds(20), 60);
tylerliu0b6d0db2020-09-28 17:52:02 -0700333}
334
tylerliu0b6d0db2020-09-28 17:52:02 -0700335BOOST_AUTO_TEST_CASE(HandleNewWithInvalidLength1)
336{
337 auto identity = addIdentity(Name("/ndn"));
338 auto key = identity.getDefaultKey();
339 auto cert = key.getDefaultCertificate();
340
341 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700342 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1");
tylerliu0b6d0db2020-09-28 17:52:02 -0700343 advanceClocks(time::milliseconds(20), 60);
344
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700345 CaProfile item;
tylerliu0b6d0db2020-09-28 17:52:02 -0700346 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700347 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700348 RequesterState state(m_keyChain, item, RequestType::NEW);
349
tylerliu0b6d0db2020-09-28 17:52:02 -0700350 auto current_tp = time::system_clock::now();
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700351 auto interest1 = Requester::genNewInterest(state, Name("/ndn"), current_tp, current_tp + time::days(1));
352 auto interest2 = Requester::genNewInterest(state, Name("/ndn/a/b/c/d"), current_tp, current_tp + time::days(1));
tylerliu0b6d0db2020-09-28 17:52:02 -0700353 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700354 auto contentTlv = response.getContent();
355 contentTlv.parse();
356 auto errorCode = static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv_error_code)));
357 BOOST_CHECK(errorCode != ErrorCode::NO_ERROR);
tylerliu0b6d0db2020-09-28 17:52:02 -0700358 });
359 face.receive(*interest1);
360 face.receive(*interest2);
361
362 advanceClocks(time::milliseconds(20), 60);
363}
364
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700365BOOST_AUTO_TEST_CASE(HandleChallenge)
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800366{
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700367 auto identity = addIdentity(Name("/ndn"));
368 auto key = identity.getDefaultKey();
369 auto cert = key.getDefaultCertificate();
370
Zhiyi Zhang22998612020-09-25 14:43:23 -0700371 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700372 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800373 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700374
375 // generate NEW Interest
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700376 CaProfile item;
Suyong Won256c9062020-05-11 02:45:56 -0700377 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700378 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700379 RequesterState state(m_keyChain, item, RequestType::NEW);
380
381 auto newInterest = Requester::genNewInterest(state, Name("/ndn/zhiyi"), time::system_clock::now(),
382 time::system_clock::now() + time::days(1));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700383
384 // generate CHALLENGE Interest
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700385 shared_ptr<Interest> challengeInterest = nullptr;
386 shared_ptr<Interest> challengeInterest2 = nullptr;
387 shared_ptr<Interest> challengeInterest3 = nullptr;
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800388
389 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700390 face.onSendData.connect([&](const Data& response) {
swa770de007bc2020-03-24 21:26:21 -0700391 if (Name("/ndn/CA/NEW").isPrefixOf(response.getName())) {
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700392 auto challengeList = Requester::onNewRenewRevokeResponse(state, response);
393 auto paramList = Requester::selectOrContinueChallenge(state, "pin");
394 challengeInterest = Requester::genChallengeInterest(state, std::move(paramList));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700395 }
swa770de007bc2020-03-24 21:26:21 -0700396 else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 0) {
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800397 count++;
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700398 BOOST_CHECK(security::verifySignature(response, cert));
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800399
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700400 Requester::onChallengeResponse(state, response);
401 BOOST_CHECK(state.m_status == Status::CHALLENGE);
402 BOOST_CHECK_EQUAL(state.m_challengeStatus, ChallengePin::NEED_CODE);
403 auto paramList = Requester::selectOrContinueChallenge(state, "pin");
404 challengeInterest2 = Requester::genChallengeInterest(state, std::move(paramList));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700405 }
swa770de007bc2020-03-24 21:26:21 -0700406 else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 1) {
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700407 count++;
408 BOOST_CHECK(security::verifySignature(response, cert));
409
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700410 Requester::onChallengeResponse(state, response);
411 BOOST_CHECK(state.m_status == Status::CHALLENGE);
412 BOOST_CHECK_EQUAL(state.m_challengeStatus, ChallengePin::WRONG_CODE);
Davide Pesavento914d05f2019-07-13 16:20:19 -0400413
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700414 auto paramList = Requester::selectOrContinueChallenge(state, "pin");
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700415 auto request = ca.getCertificateRequest(*challengeInterest2);
Zhiyi Zhanga749f442020-09-29 17:19:51 -0700416 auto secret = request.m_challengeState->m_secrets.get(ChallengePin::PARAMETER_KEY_CODE, "");
Zhiyi Zhang46049832020-09-28 17:08:12 -0700417 std::get<1>(paramList[0]) = secret;
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700418 challengeInterest3 = Requester::genChallengeInterest(state, std::move(paramList));
419 std::cout << "CHALLENGE Interest Size: " << challengeInterest3->wireEncode().size() << std::endl;
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700420 }
swa770de007bc2020-03-24 21:26:21 -0700421 else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 2) {
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700422 count++;
423 BOOST_CHECK(security::verifySignature(response, cert));
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700424 Requester::onChallengeResponse(state, response);
425 BOOST_CHECK(state.m_status == Status::SUCCESS);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700426 }
Davide Pesavento914d05f2019-07-13 16:20:19 -0400427 });
428
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700429 face.receive(*newInterest);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800430 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700431 face.receive(*challengeInterest);
432 advanceClocks(time::milliseconds(20), 60);
433 face.receive(*challengeInterest2);
434 advanceClocks(time::milliseconds(20), 60);
435 face.receive(*challengeInterest3);
436 advanceClocks(time::milliseconds(20), 60);
437 BOOST_CHECK_EQUAL(count, 3);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800438}
439
tylerliu182bc532020-09-25 01:54:45 -0700440BOOST_AUTO_TEST_CASE(HandleRevoke)
441{
442 auto identity = addIdentity(Name("/ndn"));
443 auto key = identity.getDefaultKey();
444 auto cert = key.getDefaultCertificate();
445
Zhiyi Zhang46049832020-09-28 17:08:12 -0700446 util::DummyClientFace face(io, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700447 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
tylerliu182bc532020-09-25 01:54:45 -0700448 advanceClocks(time::milliseconds(20), 60);
449
450 //generate a certificate
451 auto clientIdentity = m_keyChain.createIdentity("/ndn/qwerty");
452 auto clientKey = clientIdentity.getDefaultKey();
453 security::v2::Certificate clientCert;
454 clientCert.setName(Name(clientKey.getName()).append("cert-request").appendVersion());
455 clientCert.setContentType(tlv::ContentType_Key);
456 clientCert.setFreshnessPeriod(time::hours(24));
457 clientCert.setContent(clientKey.getPublicKey().data(), clientKey.getPublicKey().size());
458 SignatureInfo signatureInfo;
459 signatureInfo.setValidityPeriod(security::ValidityPeriod(time::system_clock::now(),
Zhiyi Zhang46049832020-09-28 17:08:12 -0700460 time::system_clock::now() + time::hours(10)));
tylerliu182bc532020-09-25 01:54:45 -0700461 m_keyChain.sign(clientCert, signingByKey(clientKey.getName()).setSignatureInfo(signatureInfo));
tylerliu8e170d62020-09-30 01:31:53 -0700462 RequestState certRequest(Name("/ndn"), "122", RequestType::NEW, Status::SUCCESS, clientCert, makeEmptyBlock(tlv::ContentType_Key));
tylerliu182bc532020-09-25 01:54:45 -0700463 auto issuedCert = ca.issueCertificate(certRequest);
464
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700465 CaProfile item;
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700466 item.m_caPrefix = Name("/ndn");
467 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700468 RequesterState state(m_keyChain, item, RequestType::REVOKE);
tylerliu182bc532020-09-25 01:54:45 -0700469
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700470 auto interest = Requester::genRevokeInterest(state, issuedCert);
tylerliu182bc532020-09-25 01:54:45 -0700471
472 int count = 0;
Zhiyi Zhang46049832020-09-28 17:08:12 -0700473 face.onSendData.connect([&](const Data& response) {
tylerliu182bc532020-09-25 01:54:45 -0700474 count++;
475 BOOST_CHECK(security::verifySignature(response, cert));
476 auto contentBlock = response.getContent();
477 contentBlock.parse();
478
479 BOOST_CHECK(readString(contentBlock.get(tlv_ecdh_pub)) != "");
480 BOOST_CHECK(readString(contentBlock.get(tlv_salt)) != "");
481 BOOST_CHECK(readString(contentBlock.get(tlv_request_id)) != "");
482
483 auto challengeBlockCount = 0;
484 for (auto const& element : contentBlock.elements()) {
Zhiyi Zhang46049832020-09-28 17:08:12 -0700485 if (element.type() == tlv_challenge) {
486 challengeBlockCount++;
487 }
tylerliu182bc532020-09-25 01:54:45 -0700488 }
489
490 BOOST_CHECK(challengeBlockCount != 0);
491
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700492 auto challengeList = Requester::onNewRenewRevokeResponse(state, response);
tylerliu8e170d62020-09-30 01:31:53 -0700493 auto ca_encryption_key = ca.getCaStorage()->getRequest(readString(contentBlock.get(tlv_request_id))).m_encryptionKey;
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700494 BOOST_CHECK_EQUAL_COLLECTIONS(state.m_aesKey, state.m_aesKey + sizeof(state.m_aesKey),
tylerliu8e170d62020-09-30 01:31:53 -0700495 ca_encryption_key.value(), ca_encryption_key.value() + ca_encryption_key.value_size());
tylerliu182bc532020-09-25 01:54:45 -0700496 });
497 face.receive(*interest);
498
499 advanceClocks(time::milliseconds(20), 60);
500 BOOST_CHECK_EQUAL(count, 1);
501}
502
503BOOST_AUTO_TEST_CASE(HandleRevokeWithBadCert)
504{
505 auto identity = addIdentity(Name("/ndn"));
506 auto key = identity.getDefaultKey();
507 auto cert = key.getDefaultCertificate();
508
Zhiyi Zhang46049832020-09-28 17:08:12 -0700509 util::DummyClientFace face(io, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700510 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
tylerliu182bc532020-09-25 01:54:45 -0700511 advanceClocks(time::milliseconds(20), 60);
512
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700513 // generate a certificate
tylerliu182bc532020-09-25 01:54:45 -0700514 auto clientIdentity = m_keyChain.createIdentity("/ndn/qwerty");
515 auto clientKey = clientIdentity.getDefaultKey();
516 security::v2::Certificate clientCert;
517 clientCert.setName(Name(clientKey.getName()).append("NDNCERT").append(std::to_string(1473283247810732701)));
518 clientCert.setContentType(tlv::ContentType_Key);
519 clientCert.setFreshnessPeriod(time::hours(24));
520 clientCert.setContent(clientKey.getPublicKey().data(), clientKey.getPublicKey().size());
521 SignatureInfo signatureInfo;
522 signatureInfo.setValidityPeriod(security::ValidityPeriod(time::system_clock::now(),
Zhiyi Zhang46049832020-09-28 17:08:12 -0700523 time::system_clock::now() + time::hours(10)));
tylerliu182bc532020-09-25 01:54:45 -0700524 m_keyChain.sign(clientCert, signingByKey(clientKey.getName()).setSignatureInfo(signatureInfo));
525
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700526 CaProfile item;
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700527 item.m_caPrefix = Name("/ndn");
528 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700529 RequesterState state(m_keyChain, item, RequestType::NEW);
tylerliu182bc532020-09-25 01:54:45 -0700530
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700531 auto interest = Requester::genRevokeInterest(state, clientCert);
tylerliu182bc532020-09-25 01:54:45 -0700532
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700533 bool receiveData = false;
Zhiyi Zhang46049832020-09-28 17:08:12 -0700534 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700535 receiveData = true;
536 auto contentTlv = response.getContent();
537 contentTlv.parse();
538 BOOST_CHECK(static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv_error_code))) != ErrorCode::NO_ERROR);
tylerliu182bc532020-09-25 01:54:45 -0700539 });
540 face.receive(*interest);
541
542 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700543 BOOST_CHECK_EQUAL(receiveData, true);
tylerliu182bc532020-09-25 01:54:45 -0700544}
545
Zhiyi Zhang46049832020-09-28 17:08:12 -0700546BOOST_AUTO_TEST_SUITE_END() // TestCaModule
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800547
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700548} // namespace tests
549} // namespace ndncert
550} // namespace ndn