blob: 062b5026de3bfd43b26841cdfc47a2280f22312a [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
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080041 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070042 BOOST_CHECK_EQUAL(ca.m_registeredPrefixHandles.size(), 2);
Zhiyi Zhang46049832020-09-28 17:08:12 -070043 BOOST_CHECK_EQUAL(ca.m_interestFilterHandles.size(), 5); // onInfo, onProbe, onNew, onChallenge, onRevoke
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080044}
45
swa77020643ac2020-03-26 02:24:45 -070046BOOST_AUTO_TEST_CASE(HandleInfo)
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070047{
48 auto identity = addIdentity(Name("/ndn"));
49 auto key = identity.getDefaultKey();
50 auto cert = key.getDefaultCertificate();
51
Zhiyi Zhang22998612020-09-25 14:43:23 -070052 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -070053 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070054 advanceClocks(time::milliseconds(20), 60);
55
swa77020643ac2020-03-26 02:24:45 -070056 Interest interest("/ndn/CA/INFO");
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070057 interest.setCanBePrefix(false);
58
59 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -070060 face.onSendData.connect([&](const Data& response) {
61 count++;
62 BOOST_CHECK(security::verifySignature(response, cert));
63 auto contentBlock = response.getContent();
64 contentBlock.parse();
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -070065 auto caItem = INFO::decodeDataContent(contentBlock);
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -070066 BOOST_CHECK_EQUAL(caItem.m_caPrefix, "/ndn");
Zhiyi Zhangb940aa12020-09-30 16:38:57 -070067 BOOST_CHECK_EQUAL(caItem.m_probeParameterKeys.size(), 1);
Zhiyi Zhang9829da92020-09-30 16:19:34 -070068 BOOST_CHECK_EQUAL(caItem.m_cert->wireEncode(), cert.wireEncode());
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -070069 BOOST_CHECK_EQUAL(caItem.m_caInfo, "ndn testbed ca");
70 });
Zhiyi Zhangf5246c42017-01-26 09:39:20 -080071 face.receive(interest);
72
73 advanceClocks(time::milliseconds(20), 60);
74 BOOST_CHECK_EQUAL(count, 1);
75}
76
Zhiyi Zhang6f395812020-09-29 14:42:03 -070077BOOST_AUTO_TEST_CASE(HandleProbe)
78{
79 auto identity = addIdentity(Name("/ndn"));
80 auto key = identity.getDefaultKey();
81 auto cert = key.getDefaultCertificate();
82
83 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -070084 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhang6f395812020-09-29 14:42:03 -070085 ca.setNameAssignmentFunction([&](const std::vector<std::tuple<std::string, std::string>>) -> std::vector<std::string> {
86 std::vector<std::string> result;
87 result.push_back("example");
88 return result;
89 });
90 advanceClocks(time::milliseconds(20), 60);
91
92 Interest interest("/ndn/CA/PROBE");
93 interest.setCanBePrefix(false);
94
95 Block paramTLV = makeEmptyBlock(tlv::ApplicationParameters);
96 paramTLV.push_back(makeStringBlock(tlv_parameter_key, "name"));
97 paramTLV.push_back(makeStringBlock(tlv_parameter_value, "zhiyi"));
98 paramTLV.encode();
99
100 interest.setApplicationParameters(paramTLV);
101
102 int count = 0;
103 face.onSendData.connect([&](const Data& response) {
104 count++;
105 BOOST_CHECK(security::verifySignature(response, cert));
106 Block contentBlock = response.getContent();
107 contentBlock.parse();
108 Block probeResponse = contentBlock.get(tlv_probe_response);
109 probeResponse.parse();
110 Name caName;
111 caName.wireDecode(probeResponse.get(tlv::Name));
112 BOOST_CHECK_EQUAL(caName, "/ndn/example");
113 });
114 face.receive(interest);
115
116 advanceClocks(time::milliseconds(20), 60);
117 BOOST_CHECK_EQUAL(count, 1);
118}
119
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700120BOOST_AUTO_TEST_CASE(HandleProbeUsingDefaultHandler)
121{
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700122 auto identity = addIdentity(Name("/ndn"));
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700123 auto key = identity.getDefaultKey();
124 auto cert = key.getDefaultCertificate();
125
Zhiyi Zhang22998612020-09-25 14:43:23 -0700126 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700127 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700128 advanceClocks(time::milliseconds(20), 60);
129
swa770de007bc2020-03-24 21:26:21 -0700130 Interest interest("/ndn/CA/PROBE");
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700131 interest.setCanBePrefix(false);
Suyong Won7968f7a2020-05-12 01:01:25 -0700132
133 Block paramTLV = makeEmptyBlock(tlv::ApplicationParameters);
Zhiyi Zhang6f395812020-09-29 14:42:03 -0700134 paramTLV.push_back(makeStringBlock(tlv_parameter_key, "name"));
Suyong Won7968f7a2020-05-12 01:01:25 -0700135 paramTLV.push_back(makeStringBlock(tlv_parameter_value, "zhiyi"));
136 paramTLV.encode();
137
138 interest.setApplicationParameters(paramTLV);
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700139
140 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700141 face.onSendData.connect([&](const Data& response) {
142 count++;
143 BOOST_CHECK(security::verifySignature(response, cert));
144 auto contentBlock = response.getContent();
145 contentBlock.parse();
146 auto probeResponseBlock = contentBlock.get(tlv_probe_response);
147 probeResponseBlock.parse();
148 Name caPrefix;
149 caPrefix.wireDecode(probeResponseBlock.get(tlv::Name));
150 BOOST_CHECK(caPrefix != "");
151 });
Zhiyi Zhanga63b7372017-05-17 14:14:34 -0700152 face.receive(interest);
153
154 advanceClocks(time::milliseconds(20), 60);
155 BOOST_CHECK_EQUAL(count, 1);
156}
157
Suyong Wone2afeb52020-10-04 03:05:39 +0900158BOOST_AUTO_TEST_CASE(HandleProbeRedirection)
159{
160 auto identity = addIdentity(Name("/ndn"));
161 auto key = identity.getDefaultKey();
162 auto cert = key.getDefaultCertificate();
163
164 util::DummyClientFace face(io, m_keyChain, {true, true});
165 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-5", "ca-storage-memory");
166 ca.setNameAssignmentFunction([&](const std::vector<std::tuple<std::string, std::string>>) -> std::vector<std::string> {
167 std::vector<std::string> result;
168 result.push_back("example");
169 return result;
170 });
171 advanceClocks(time::milliseconds(20), 60);
172
173 Interest interest("/ndn/CA/PROBE");
174 interest.setCanBePrefix(false);
175
176 Block paramTLV = makeEmptyBlock(tlv::ApplicationParameters);
177 paramTLV.push_back(makeStringBlock(tlv_parameter_key, "name"));
178 paramTLV.push_back(makeStringBlock(tlv_parameter_value, "zhiyi"));
179 paramTLV.encode();
180
181 interest.setApplicationParameters(paramTLV);
182
183 int count = 0;
184 face.onSendData.connect([&](const Data& response) {
185 count++;
186 BOOST_CHECK(security::verifySignature(response, cert));
187 Block contentBlock = response.getContent();
188 contentBlock.parse();
189
190 // Test CA sent redirections
Zhiyi Zhang34a8d432020-10-03 22:14:25 -0700191 std::vector<Name> redirectionItems;
192 for (auto item : contentBlock.elements()) {
193 if (item.type() == tlv_probe_redirect) {
194 redirectionItems.push_back(Name(item.blockFromValue()));
195 }
Suyong Wone2afeb52020-10-04 03:05:39 +0900196 }
Zhiyi Zhang34a8d432020-10-03 22:14:25 -0700197 BOOST_CHECK_EQUAL(redirectionItems.size(), 2);
198 BOOST_CHECK_EQUAL(security::v2::extractIdentityFromCertName(redirectionItems[0].getPrefix(-1)), "/ndn/site1");
199 BOOST_CHECK_EQUAL(security::v2::extractIdentityFromCertName(redirectionItems[1].getPrefix(-1)), "/ndn/site1");
Suyong Wone2afeb52020-10-04 03:05:39 +0900200 });
201 face.receive(interest);
202 advanceClocks(time::milliseconds(20), 60);
203 BOOST_CHECK_EQUAL(count, 1);
204}
205
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800206BOOST_AUTO_TEST_CASE(HandleNew)
207{
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700208 auto identity = addIdentity(Name("/ndn"));
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800209 auto key = identity.getDefaultKey();
210 auto cert = key.getDefaultCertificate();
211
Zhiyi Zhang22998612020-09-25 14:43:23 -0700212 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700213 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800214 advanceClocks(time::milliseconds(20), 60);
215
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700216 CaProfile item;
Suyong Won256c9062020-05-11 02:45:56 -0700217 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700218 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700219 RequesterState state(m_keyChain, item, RequestType::NEW);
220 auto interest = Requester::genNewInterest(state, Name("/ndn/zhiyi"),
221 time::system_clock::now(),
222 time::system_clock::now() + time::days(1));
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800223
224 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700225 face.onSendData.connect([&](const Data& response) {
226 count++;
227 BOOST_CHECK(security::verifySignature(response, cert));
228 auto contentBlock = response.getContent();
229 contentBlock.parse();
Suyong Won7968f7a2020-05-12 01:01:25 -0700230
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700231 BOOST_CHECK(readString(contentBlock.get(tlv_ecdh_pub)) != "");
232 BOOST_CHECK(readString(contentBlock.get(tlv_salt)) != "");
233 BOOST_CHECK(readString(contentBlock.get(tlv_request_id)) != "");
Suyong Won7968f7a2020-05-12 01:01:25 -0700234
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700235 auto challengeBlockCount = 0;
236 for (auto const& element : contentBlock.elements()) {
237 if (element.type() == tlv_challenge) {
238 challengeBlockCount++;
Suyong Won7968f7a2020-05-12 01:01:25 -0700239 }
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700240 }
Suyong Won7968f7a2020-05-12 01:01:25 -0700241
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700242 BOOST_CHECK(challengeBlockCount != 0);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700243
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700244 auto challengeList = Requester::onNewRenewRevokeResponse(state, response);
tylerliu8e170d62020-09-30 01:31:53 -0700245 auto ca_encryption_key = ca.getCaStorage()->getRequest(readString(contentBlock.get(tlv_request_id))).m_encryptionKey;
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700246 BOOST_CHECK_EQUAL_COLLECTIONS(state.m_aesKey, state.m_aesKey + sizeof(state.m_aesKey),
tylerliu8e170d62020-09-30 01:31:53 -0700247 ca_encryption_key.value(), ca_encryption_key.value() + ca_encryption_key.value_size());
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700248 });
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700249 face.receive(*interest);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800250
251 advanceClocks(time::milliseconds(20), 60);
252 BOOST_CHECK_EQUAL(count, 1);
253}
254
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700255BOOST_AUTO_TEST_CASE(HandleNewWithInvalidValidityPeriod1)
256{
257 auto identity = addIdentity(Name("/ndn"));
258 auto key = identity.getDefaultKey();
259 auto cert = key.getDefaultCertificate();
260
Zhiyi Zhang22998612020-09-25 14:43:23 -0700261 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700262 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1");
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700263 advanceClocks(time::milliseconds(20), 60);
264
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700265 CaProfile item;
Suyong Won256c9062020-05-11 02:45:56 -0700266 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700267 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700268 RequesterState state(m_keyChain, item, RequestType::NEW);
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700269 auto current_tp = time::system_clock::now();
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700270 auto interest1 = Requester::genNewInterest(state, Name("/ndn/zhiyi"), current_tp, current_tp - time::hours(1));
271 auto interest2 = Requester::genNewInterest(state, Name("/ndn/zhiyi"), current_tp, current_tp + time::days(361));
272 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 -0700273 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700274 auto contentTlv = response.getContent();
275 contentTlv.parse();
276 auto errorCode = static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv_error_code)));
277 BOOST_CHECK(errorCode != ErrorCode::NO_ERROR);
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700278 });
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700279 face.receive(*interest1);
280 face.receive(*interest2);
281 face.receive(*interest3);
282
283 advanceClocks(time::milliseconds(20), 60);
284}
285
tylerliu0b6d0db2020-09-28 17:52:02 -0700286BOOST_AUTO_TEST_CASE(HandleNewWithLongSuffix)
287{
288 auto identity = addIdentity(Name("/ndn"));
289 auto key = identity.getDefaultKey();
290 auto cert = key.getDefaultCertificate();
291
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700292 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700293 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
tylerliu0b6d0db2020-09-28 17:52:02 -0700294 advanceClocks(time::milliseconds(20), 60);
295
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700296 CaProfile item;
tylerliu0b6d0db2020-09-28 17:52:02 -0700297 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700298 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700299 RequesterState state(m_keyChain, item, RequestType::NEW);
tylerliu0b6d0db2020-09-28 17:52:02 -0700300
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700301 auto interest1 = Requester::genNewInterest(state, Name("/ndn/a"), time::system_clock::now(),
302 time::system_clock::now() + time::days(1));
303 auto interest2 = Requester::genNewInterest(state, Name("/ndn/a/b"), time::system_clock::now(),
304 time::system_clock::now() + time::days(1));
305 auto interest3 = Requester::genNewInterest(state, Name("/ndn/a/b/c/d"), time::system_clock::now(),
306 time::system_clock::now() + time::days(1));
tylerliu0b6d0db2020-09-28 17:52:02 -0700307
tylerliu0b6d0db2020-09-28 17:52:02 -0700308 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700309 auto contentTlv = response.getContent();
310 contentTlv.parse();
311 if (interest3->getName().isPrefixOf(response.getName())) {
312 auto errorCode = static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv_error_code)));
313 BOOST_CHECK(errorCode != ErrorCode::NO_ERROR);
314 }
315 else {
316 // should successfully get responses
317 BOOST_CHECK_EXCEPTION(readNonNegativeInteger(contentTlv.get(tlv_error_code)), std::runtime_error,
318 [](const auto& e) { return true; });
319 }
tylerliu0b6d0db2020-09-28 17:52:02 -0700320 });
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700321 face.receive(*interest1);
322 face.receive(*interest2);
323 face.receive(*interest3);
tylerliu0b6d0db2020-09-28 17:52:02 -0700324 advanceClocks(time::milliseconds(20), 60);
tylerliu0b6d0db2020-09-28 17:52:02 -0700325}
326
tylerliu0b6d0db2020-09-28 17:52:02 -0700327BOOST_AUTO_TEST_CASE(HandleNewWithInvalidLength1)
328{
329 auto identity = addIdentity(Name("/ndn"));
330 auto key = identity.getDefaultKey();
331 auto cert = key.getDefaultCertificate();
332
333 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700334 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1");
tylerliu0b6d0db2020-09-28 17:52:02 -0700335 advanceClocks(time::milliseconds(20), 60);
336
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700337 CaProfile item;
tylerliu0b6d0db2020-09-28 17:52:02 -0700338 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700339 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700340 RequesterState state(m_keyChain, item, RequestType::NEW);
341
tylerliu0b6d0db2020-09-28 17:52:02 -0700342 auto current_tp = time::system_clock::now();
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700343 auto interest1 = Requester::genNewInterest(state, Name("/ndn"), current_tp, current_tp + time::days(1));
344 auto interest2 = Requester::genNewInterest(state, Name("/ndn/a/b/c/d"), current_tp, current_tp + time::days(1));
tylerliu0b6d0db2020-09-28 17:52:02 -0700345 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700346 auto contentTlv = response.getContent();
347 contentTlv.parse();
348 auto errorCode = static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv_error_code)));
349 BOOST_CHECK(errorCode != ErrorCode::NO_ERROR);
tylerliu0b6d0db2020-09-28 17:52:02 -0700350 });
351 face.receive(*interest1);
352 face.receive(*interest2);
353
354 advanceClocks(time::milliseconds(20), 60);
355}
356
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700357BOOST_AUTO_TEST_CASE(HandleChallenge)
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800358{
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700359 auto identity = addIdentity(Name("/ndn"));
360 auto key = identity.getDefaultKey();
361 auto cert = key.getDefaultCertificate();
362
Zhiyi Zhang22998612020-09-25 14:43:23 -0700363 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700364 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800365 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700366
367 // generate NEW Interest
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700368 CaProfile item;
Suyong Won256c9062020-05-11 02:45:56 -0700369 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700370 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700371 RequesterState state(m_keyChain, item, RequestType::NEW);
372
373 auto newInterest = Requester::genNewInterest(state, Name("/ndn/zhiyi"), time::system_clock::now(),
374 time::system_clock::now() + time::days(1));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700375
376 // generate CHALLENGE Interest
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700377 shared_ptr<Interest> challengeInterest = nullptr;
378 shared_ptr<Interest> challengeInterest2 = nullptr;
379 shared_ptr<Interest> challengeInterest3 = nullptr;
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800380
381 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700382 face.onSendData.connect([&](const Data& response) {
swa770de007bc2020-03-24 21:26:21 -0700383 if (Name("/ndn/CA/NEW").isPrefixOf(response.getName())) {
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700384 auto challengeList = Requester::onNewRenewRevokeResponse(state, response);
385 auto paramList = Requester::selectOrContinueChallenge(state, "pin");
386 challengeInterest = Requester::genChallengeInterest(state, std::move(paramList));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700387 }
swa770de007bc2020-03-24 21:26:21 -0700388 else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 0) {
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800389 count++;
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700390 BOOST_CHECK(security::verifySignature(response, cert));
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800391
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700392 Requester::onChallengeResponse(state, response);
393 BOOST_CHECK(state.m_status == Status::CHALLENGE);
394 BOOST_CHECK_EQUAL(state.m_challengeStatus, ChallengePin::NEED_CODE);
395 auto paramList = Requester::selectOrContinueChallenge(state, "pin");
396 challengeInterest2 = Requester::genChallengeInterest(state, std::move(paramList));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700397 }
swa770de007bc2020-03-24 21:26:21 -0700398 else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 1) {
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700399 count++;
400 BOOST_CHECK(security::verifySignature(response, cert));
401
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700402 Requester::onChallengeResponse(state, response);
403 BOOST_CHECK(state.m_status == Status::CHALLENGE);
404 BOOST_CHECK_EQUAL(state.m_challengeStatus, ChallengePin::WRONG_CODE);
Davide Pesavento914d05f2019-07-13 16:20:19 -0400405
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700406 auto paramList = Requester::selectOrContinueChallenge(state, "pin");
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700407 auto request = ca.getCertificateRequest(*challengeInterest2);
Zhiyi Zhanga749f442020-09-29 17:19:51 -0700408 auto secret = request.m_challengeState->m_secrets.get(ChallengePin::PARAMETER_KEY_CODE, "");
Zhiyi Zhang46049832020-09-28 17:08:12 -0700409 std::get<1>(paramList[0]) = secret;
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700410 challengeInterest3 = Requester::genChallengeInterest(state, std::move(paramList));
411 std::cout << "CHALLENGE Interest Size: " << challengeInterest3->wireEncode().size() << std::endl;
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700412 }
swa770de007bc2020-03-24 21:26:21 -0700413 else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 2) {
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700414 count++;
415 BOOST_CHECK(security::verifySignature(response, cert));
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700416 Requester::onChallengeResponse(state, response);
417 BOOST_CHECK(state.m_status == Status::SUCCESS);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700418 }
Davide Pesavento914d05f2019-07-13 16:20:19 -0400419 });
420
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700421 face.receive(*newInterest);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800422 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700423 face.receive(*challengeInterest);
424 advanceClocks(time::milliseconds(20), 60);
425 face.receive(*challengeInterest2);
426 advanceClocks(time::milliseconds(20), 60);
427 face.receive(*challengeInterest3);
428 advanceClocks(time::milliseconds(20), 60);
429 BOOST_CHECK_EQUAL(count, 3);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800430}
431
tylerliu182bc532020-09-25 01:54:45 -0700432BOOST_AUTO_TEST_CASE(HandleRevoke)
433{
434 auto identity = addIdentity(Name("/ndn"));
435 auto key = identity.getDefaultKey();
436 auto cert = key.getDefaultCertificate();
437
Zhiyi Zhang46049832020-09-28 17:08:12 -0700438 util::DummyClientFace face(io, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700439 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
tylerliu182bc532020-09-25 01:54:45 -0700440 advanceClocks(time::milliseconds(20), 60);
441
442 //generate a certificate
443 auto clientIdentity = m_keyChain.createIdentity("/ndn/qwerty");
444 auto clientKey = clientIdentity.getDefaultKey();
445 security::v2::Certificate clientCert;
446 clientCert.setName(Name(clientKey.getName()).append("cert-request").appendVersion());
447 clientCert.setContentType(tlv::ContentType_Key);
448 clientCert.setFreshnessPeriod(time::hours(24));
449 clientCert.setContent(clientKey.getPublicKey().data(), clientKey.getPublicKey().size());
450 SignatureInfo signatureInfo;
451 signatureInfo.setValidityPeriod(security::ValidityPeriod(time::system_clock::now(),
Zhiyi Zhang46049832020-09-28 17:08:12 -0700452 time::system_clock::now() + time::hours(10)));
tylerliu182bc532020-09-25 01:54:45 -0700453 m_keyChain.sign(clientCert, signingByKey(clientKey.getName()).setSignatureInfo(signatureInfo));
tylerliu8704d032020-06-23 10:18:15 -0700454 CaState certRequest(Name("/ndn"), "122", RequestType::NEW, Status::SUCCESS, clientCert, makeEmptyBlock(tlv::ContentType_Key));
tylerliu182bc532020-09-25 01:54:45 -0700455 auto issuedCert = ca.issueCertificate(certRequest);
456
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700457 CaProfile item;
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700458 item.m_caPrefix = Name("/ndn");
459 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700460 RequesterState state(m_keyChain, item, RequestType::REVOKE);
tylerliu182bc532020-09-25 01:54:45 -0700461
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700462 auto interest = Requester::genRevokeInterest(state, issuedCert);
tylerliu182bc532020-09-25 01:54:45 -0700463
464 int count = 0;
Zhiyi Zhang46049832020-09-28 17:08:12 -0700465 face.onSendData.connect([&](const Data& response) {
tylerliu182bc532020-09-25 01:54:45 -0700466 count++;
467 BOOST_CHECK(security::verifySignature(response, cert));
468 auto contentBlock = response.getContent();
469 contentBlock.parse();
470
471 BOOST_CHECK(readString(contentBlock.get(tlv_ecdh_pub)) != "");
472 BOOST_CHECK(readString(contentBlock.get(tlv_salt)) != "");
473 BOOST_CHECK(readString(contentBlock.get(tlv_request_id)) != "");
474
475 auto challengeBlockCount = 0;
476 for (auto const& element : contentBlock.elements()) {
Zhiyi Zhang46049832020-09-28 17:08:12 -0700477 if (element.type() == tlv_challenge) {
478 challengeBlockCount++;
479 }
tylerliu182bc532020-09-25 01:54:45 -0700480 }
481
482 BOOST_CHECK(challengeBlockCount != 0);
483
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700484 auto challengeList = Requester::onNewRenewRevokeResponse(state, response);
tylerliu8e170d62020-09-30 01:31:53 -0700485 auto ca_encryption_key = ca.getCaStorage()->getRequest(readString(contentBlock.get(tlv_request_id))).m_encryptionKey;
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700486 BOOST_CHECK_EQUAL_COLLECTIONS(state.m_aesKey, state.m_aesKey + sizeof(state.m_aesKey),
tylerliu8e170d62020-09-30 01:31:53 -0700487 ca_encryption_key.value(), ca_encryption_key.value() + ca_encryption_key.value_size());
tylerliu182bc532020-09-25 01:54:45 -0700488 });
489 face.receive(*interest);
490
491 advanceClocks(time::milliseconds(20), 60);
492 BOOST_CHECK_EQUAL(count, 1);
493}
494
495BOOST_AUTO_TEST_CASE(HandleRevokeWithBadCert)
496{
497 auto identity = addIdentity(Name("/ndn"));
498 auto key = identity.getDefaultKey();
499 auto cert = key.getDefaultCertificate();
500
Zhiyi Zhang46049832020-09-28 17:08:12 -0700501 util::DummyClientFace face(io, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700502 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
tylerliu182bc532020-09-25 01:54:45 -0700503 advanceClocks(time::milliseconds(20), 60);
504
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700505 // generate a certificate
tylerliu182bc532020-09-25 01:54:45 -0700506 auto clientIdentity = m_keyChain.createIdentity("/ndn/qwerty");
507 auto clientKey = clientIdentity.getDefaultKey();
508 security::v2::Certificate clientCert;
509 clientCert.setName(Name(clientKey.getName()).append("NDNCERT").append(std::to_string(1473283247810732701)));
510 clientCert.setContentType(tlv::ContentType_Key);
511 clientCert.setFreshnessPeriod(time::hours(24));
512 clientCert.setContent(clientKey.getPublicKey().data(), clientKey.getPublicKey().size());
513 SignatureInfo signatureInfo;
514 signatureInfo.setValidityPeriod(security::ValidityPeriod(time::system_clock::now(),
Zhiyi Zhang46049832020-09-28 17:08:12 -0700515 time::system_clock::now() + time::hours(10)));
tylerliu182bc532020-09-25 01:54:45 -0700516 m_keyChain.sign(clientCert, signingByKey(clientKey.getName()).setSignatureInfo(signatureInfo));
517
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700518 CaProfile item;
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700519 item.m_caPrefix = Name("/ndn");
520 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700521 RequesterState state(m_keyChain, item, RequestType::NEW);
tylerliu182bc532020-09-25 01:54:45 -0700522
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700523 auto interest = Requester::genRevokeInterest(state, clientCert);
tylerliu182bc532020-09-25 01:54:45 -0700524
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700525 bool receiveData = false;
Zhiyi Zhang46049832020-09-28 17:08:12 -0700526 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700527 receiveData = true;
528 auto contentTlv = response.getContent();
529 contentTlv.parse();
530 BOOST_CHECK(static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv_error_code))) != ErrorCode::NO_ERROR);
tylerliu182bc532020-09-25 01:54:45 -0700531 });
532 face.receive(*interest);
533
534 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700535 BOOST_CHECK_EQUAL(receiveData, true);
tylerliu182bc532020-09-25 01:54:45 -0700536}
537
Zhiyi Zhang46049832020-09-28 17:08:12 -0700538BOOST_AUTO_TEST_SUITE_END() // TestCaModule
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800539
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700540} // namespace tests
541} // namespace ndncert
542} // namespace ndn