blob: d18931f9995b7178e8a220d9590fad51f70b1de5 [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
Zhiyi Zhang34a8d432020-10-03 22:14:25 -0700197 std::vector<Name> redirectionItems;
198 for (auto item : contentBlock.elements()) {
199 if (item.type() == tlv_probe_redirect) {
200 redirectionItems.push_back(Name(item.blockFromValue()));
201 }
Suyong Wone2afeb52020-10-04 03:05:39 +0900202 }
Zhiyi Zhang34a8d432020-10-03 22:14:25 -0700203 BOOST_CHECK_EQUAL(redirectionItems.size(), 2);
204 BOOST_CHECK_EQUAL(security::v2::extractIdentityFromCertName(redirectionItems[0].getPrefix(-1)), "/ndn/site1");
205 BOOST_CHECK_EQUAL(security::v2::extractIdentityFromCertName(redirectionItems[1].getPrefix(-1)), "/ndn/site1");
Suyong Wone2afeb52020-10-04 03:05:39 +0900206 });
207 face.receive(interest);
208 advanceClocks(time::milliseconds(20), 60);
209 BOOST_CHECK_EQUAL(count, 1);
210}
211
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800212BOOST_AUTO_TEST_CASE(HandleNew)
213{
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700214 auto identity = addIdentity(Name("/ndn"));
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800215 auto key = identity.getDefaultKey();
216 auto cert = key.getDefaultCertificate();
217
Zhiyi Zhang22998612020-09-25 14:43:23 -0700218 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700219 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800220 advanceClocks(time::milliseconds(20), 60);
221
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700222 CaProfile item;
Suyong Won256c9062020-05-11 02:45:56 -0700223 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700224 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700225 RequesterState state(m_keyChain, item, RequestType::NEW);
226 auto interest = Requester::genNewInterest(state, Name("/ndn/zhiyi"),
227 time::system_clock::now(),
228 time::system_clock::now() + time::days(1));
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800229
230 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700231 face.onSendData.connect([&](const Data& response) {
232 count++;
233 BOOST_CHECK(security::verifySignature(response, cert));
234 auto contentBlock = response.getContent();
235 contentBlock.parse();
Suyong Won7968f7a2020-05-12 01:01:25 -0700236
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700237 BOOST_CHECK(readString(contentBlock.get(tlv_ecdh_pub)) != "");
238 BOOST_CHECK(readString(contentBlock.get(tlv_salt)) != "");
239 BOOST_CHECK(readString(contentBlock.get(tlv_request_id)) != "");
Suyong Won7968f7a2020-05-12 01:01:25 -0700240
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700241 auto challengeBlockCount = 0;
242 for (auto const& element : contentBlock.elements()) {
243 if (element.type() == tlv_challenge) {
244 challengeBlockCount++;
Suyong Won7968f7a2020-05-12 01:01:25 -0700245 }
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700246 }
Suyong Won7968f7a2020-05-12 01:01:25 -0700247
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700248 BOOST_CHECK(challengeBlockCount != 0);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700249
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700250 auto challengeList = Requester::onNewRenewRevokeResponse(state, response);
tylerliu8e170d62020-09-30 01:31:53 -0700251 auto ca_encryption_key = ca.getCaStorage()->getRequest(readString(contentBlock.get(tlv_request_id))).m_encryptionKey;
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700252 BOOST_CHECK_EQUAL_COLLECTIONS(state.m_aesKey, state.m_aesKey + sizeof(state.m_aesKey),
tylerliu8e170d62020-09-30 01:31:53 -0700253 ca_encryption_key.value(), ca_encryption_key.value() + ca_encryption_key.value_size());
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700254 });
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700255 face.receive(*interest);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800256
257 advanceClocks(time::milliseconds(20), 60);
258 BOOST_CHECK_EQUAL(count, 1);
259}
260
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700261BOOST_AUTO_TEST_CASE(HandleNewWithInvalidValidityPeriod1)
262{
263 auto identity = addIdentity(Name("/ndn"));
264 auto key = identity.getDefaultKey();
265 auto cert = key.getDefaultCertificate();
266
Zhiyi Zhang22998612020-09-25 14:43:23 -0700267 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700268 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1");
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700269 advanceClocks(time::milliseconds(20), 60);
270
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700271 CaProfile item;
Suyong Won256c9062020-05-11 02:45:56 -0700272 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700273 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700274 RequesterState state(m_keyChain, item, RequestType::NEW);
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700275 auto current_tp = time::system_clock::now();
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700276 auto interest1 = Requester::genNewInterest(state, Name("/ndn/zhiyi"), current_tp, current_tp - time::hours(1));
277 auto interest2 = Requester::genNewInterest(state, Name("/ndn/zhiyi"), current_tp, current_tp + time::days(361));
278 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 -0700279 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700280 auto contentTlv = response.getContent();
281 contentTlv.parse();
282 auto errorCode = static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv_error_code)));
283 BOOST_CHECK(errorCode != ErrorCode::NO_ERROR);
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700284 });
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700285 face.receive(*interest1);
286 face.receive(*interest2);
287 face.receive(*interest3);
288
289 advanceClocks(time::milliseconds(20), 60);
290}
291
tylerliu0b6d0db2020-09-28 17:52:02 -0700292BOOST_AUTO_TEST_CASE(HandleNewWithLongSuffix)
293{
294 auto identity = addIdentity(Name("/ndn"));
295 auto key = identity.getDefaultKey();
296 auto cert = key.getDefaultCertificate();
297
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700298 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700299 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
tylerliu0b6d0db2020-09-28 17:52:02 -0700300 advanceClocks(time::milliseconds(20), 60);
301
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700302 CaProfile item;
tylerliu0b6d0db2020-09-28 17:52:02 -0700303 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700304 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700305 RequesterState state(m_keyChain, item, RequestType::NEW);
tylerliu0b6d0db2020-09-28 17:52:02 -0700306
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700307 auto interest1 = Requester::genNewInterest(state, Name("/ndn/a"), time::system_clock::now(),
308 time::system_clock::now() + time::days(1));
309 auto interest2 = Requester::genNewInterest(state, Name("/ndn/a/b"), time::system_clock::now(),
310 time::system_clock::now() + time::days(1));
311 auto interest3 = Requester::genNewInterest(state, Name("/ndn/a/b/c/d"), time::system_clock::now(),
312 time::system_clock::now() + time::days(1));
tylerliu0b6d0db2020-09-28 17:52:02 -0700313
tylerliu0b6d0db2020-09-28 17:52:02 -0700314 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700315 auto contentTlv = response.getContent();
316 contentTlv.parse();
317 if (interest3->getName().isPrefixOf(response.getName())) {
318 auto errorCode = static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv_error_code)));
319 BOOST_CHECK(errorCode != ErrorCode::NO_ERROR);
320 }
321 else {
322 // should successfully get responses
323 BOOST_CHECK_EXCEPTION(readNonNegativeInteger(contentTlv.get(tlv_error_code)), std::runtime_error,
324 [](const auto& e) { return true; });
325 }
tylerliu0b6d0db2020-09-28 17:52:02 -0700326 });
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700327 face.receive(*interest1);
328 face.receive(*interest2);
329 face.receive(*interest3);
tylerliu0b6d0db2020-09-28 17:52:02 -0700330 advanceClocks(time::milliseconds(20), 60);
tylerliu0b6d0db2020-09-28 17:52:02 -0700331}
332
tylerliu0b6d0db2020-09-28 17:52:02 -0700333BOOST_AUTO_TEST_CASE(HandleNewWithInvalidLength1)
334{
335 auto identity = addIdentity(Name("/ndn"));
336 auto key = identity.getDefaultKey();
337 auto cert = key.getDefaultCertificate();
338
339 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700340 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1");
tylerliu0b6d0db2020-09-28 17:52:02 -0700341 advanceClocks(time::milliseconds(20), 60);
342
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700343 CaProfile item;
tylerliu0b6d0db2020-09-28 17:52:02 -0700344 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700345 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700346 RequesterState state(m_keyChain, item, RequestType::NEW);
347
tylerliu0b6d0db2020-09-28 17:52:02 -0700348 auto current_tp = time::system_clock::now();
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700349 auto interest1 = Requester::genNewInterest(state, Name("/ndn"), current_tp, current_tp + time::days(1));
350 auto interest2 = Requester::genNewInterest(state, Name("/ndn/a/b/c/d"), current_tp, current_tp + time::days(1));
tylerliu0b6d0db2020-09-28 17:52:02 -0700351 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700352 auto contentTlv = response.getContent();
353 contentTlv.parse();
354 auto errorCode = static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv_error_code)));
355 BOOST_CHECK(errorCode != ErrorCode::NO_ERROR);
tylerliu0b6d0db2020-09-28 17:52:02 -0700356 });
357 face.receive(*interest1);
358 face.receive(*interest2);
359
360 advanceClocks(time::milliseconds(20), 60);
361}
362
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700363BOOST_AUTO_TEST_CASE(HandleChallenge)
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800364{
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700365 auto identity = addIdentity(Name("/ndn"));
366 auto key = identity.getDefaultKey();
367 auto cert = key.getDefaultCertificate();
368
Zhiyi Zhang22998612020-09-25 14:43:23 -0700369 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700370 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800371 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700372
373 // generate NEW Interest
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700374 CaProfile item;
Suyong Won256c9062020-05-11 02:45:56 -0700375 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700376 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700377 RequesterState state(m_keyChain, item, RequestType::NEW);
378
379 auto newInterest = Requester::genNewInterest(state, Name("/ndn/zhiyi"), time::system_clock::now(),
380 time::system_clock::now() + time::days(1));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700381
382 // generate CHALLENGE Interest
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700383 shared_ptr<Interest> challengeInterest = nullptr;
384 shared_ptr<Interest> challengeInterest2 = nullptr;
385 shared_ptr<Interest> challengeInterest3 = nullptr;
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800386
387 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700388 face.onSendData.connect([&](const Data& response) {
swa770de007bc2020-03-24 21:26:21 -0700389 if (Name("/ndn/CA/NEW").isPrefixOf(response.getName())) {
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700390 auto challengeList = Requester::onNewRenewRevokeResponse(state, response);
391 auto paramList = Requester::selectOrContinueChallenge(state, "pin");
392 challengeInterest = Requester::genChallengeInterest(state, std::move(paramList));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700393 }
swa770de007bc2020-03-24 21:26:21 -0700394 else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 0) {
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800395 count++;
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700396 BOOST_CHECK(security::verifySignature(response, cert));
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800397
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700398 Requester::onChallengeResponse(state, response);
399 BOOST_CHECK(state.m_status == Status::CHALLENGE);
400 BOOST_CHECK_EQUAL(state.m_challengeStatus, ChallengePin::NEED_CODE);
401 auto paramList = Requester::selectOrContinueChallenge(state, "pin");
402 challengeInterest2 = Requester::genChallengeInterest(state, std::move(paramList));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700403 }
swa770de007bc2020-03-24 21:26:21 -0700404 else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 1) {
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700405 count++;
406 BOOST_CHECK(security::verifySignature(response, cert));
407
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700408 Requester::onChallengeResponse(state, response);
409 BOOST_CHECK(state.m_status == Status::CHALLENGE);
410 BOOST_CHECK_EQUAL(state.m_challengeStatus, ChallengePin::WRONG_CODE);
Davide Pesavento914d05f2019-07-13 16:20:19 -0400411
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700412 auto paramList = Requester::selectOrContinueChallenge(state, "pin");
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700413 auto request = ca.getCertificateRequest(*challengeInterest2);
Zhiyi Zhanga749f442020-09-29 17:19:51 -0700414 auto secret = request.m_challengeState->m_secrets.get(ChallengePin::PARAMETER_KEY_CODE, "");
Zhiyi Zhang46049832020-09-28 17:08:12 -0700415 std::get<1>(paramList[0]) = secret;
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700416 challengeInterest3 = Requester::genChallengeInterest(state, std::move(paramList));
417 std::cout << "CHALLENGE Interest Size: " << challengeInterest3->wireEncode().size() << std::endl;
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700418 }
swa770de007bc2020-03-24 21:26:21 -0700419 else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 2) {
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700420 count++;
421 BOOST_CHECK(security::verifySignature(response, cert));
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700422 Requester::onChallengeResponse(state, response);
423 BOOST_CHECK(state.m_status == Status::SUCCESS);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700424 }
Davide Pesavento914d05f2019-07-13 16:20:19 -0400425 });
426
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700427 face.receive(*newInterest);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800428 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700429 face.receive(*challengeInterest);
430 advanceClocks(time::milliseconds(20), 60);
431 face.receive(*challengeInterest2);
432 advanceClocks(time::milliseconds(20), 60);
433 face.receive(*challengeInterest3);
434 advanceClocks(time::milliseconds(20), 60);
435 BOOST_CHECK_EQUAL(count, 3);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800436}
437
tylerliu182bc532020-09-25 01:54:45 -0700438BOOST_AUTO_TEST_CASE(HandleRevoke)
439{
440 auto identity = addIdentity(Name("/ndn"));
441 auto key = identity.getDefaultKey();
442 auto cert = key.getDefaultCertificate();
443
Zhiyi Zhang46049832020-09-28 17:08:12 -0700444 util::DummyClientFace face(io, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700445 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
tylerliu182bc532020-09-25 01:54:45 -0700446 advanceClocks(time::milliseconds(20), 60);
447
448 //generate a certificate
449 auto clientIdentity = m_keyChain.createIdentity("/ndn/qwerty");
450 auto clientKey = clientIdentity.getDefaultKey();
451 security::v2::Certificate clientCert;
452 clientCert.setName(Name(clientKey.getName()).append("cert-request").appendVersion());
453 clientCert.setContentType(tlv::ContentType_Key);
454 clientCert.setFreshnessPeriod(time::hours(24));
455 clientCert.setContent(clientKey.getPublicKey().data(), clientKey.getPublicKey().size());
456 SignatureInfo signatureInfo;
457 signatureInfo.setValidityPeriod(security::ValidityPeriod(time::system_clock::now(),
Zhiyi Zhang46049832020-09-28 17:08:12 -0700458 time::system_clock::now() + time::hours(10)));
tylerliu182bc532020-09-25 01:54:45 -0700459 m_keyChain.sign(clientCert, signingByKey(clientKey.getName()).setSignatureInfo(signatureInfo));
tylerliu8704d032020-06-23 10:18:15 -0700460 CaState certRequest(Name("/ndn"), "122", RequestType::NEW, Status::SUCCESS, clientCert, makeEmptyBlock(tlv::ContentType_Key));
tylerliu182bc532020-09-25 01:54:45 -0700461 auto issuedCert = ca.issueCertificate(certRequest);
462
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700463 CaProfile item;
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700464 item.m_caPrefix = Name("/ndn");
465 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700466 RequesterState state(m_keyChain, item, RequestType::REVOKE);
tylerliu182bc532020-09-25 01:54:45 -0700467
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700468 auto interest = Requester::genRevokeInterest(state, issuedCert);
tylerliu182bc532020-09-25 01:54:45 -0700469
470 int count = 0;
Zhiyi Zhang46049832020-09-28 17:08:12 -0700471 face.onSendData.connect([&](const Data& response) {
tylerliu182bc532020-09-25 01:54:45 -0700472 count++;
473 BOOST_CHECK(security::verifySignature(response, cert));
474 auto contentBlock = response.getContent();
475 contentBlock.parse();
476
477 BOOST_CHECK(readString(contentBlock.get(tlv_ecdh_pub)) != "");
478 BOOST_CHECK(readString(contentBlock.get(tlv_salt)) != "");
479 BOOST_CHECK(readString(contentBlock.get(tlv_request_id)) != "");
480
481 auto challengeBlockCount = 0;
482 for (auto const& element : contentBlock.elements()) {
Zhiyi Zhang46049832020-09-28 17:08:12 -0700483 if (element.type() == tlv_challenge) {
484 challengeBlockCount++;
485 }
tylerliu182bc532020-09-25 01:54:45 -0700486 }
487
488 BOOST_CHECK(challengeBlockCount != 0);
489
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700490 auto challengeList = Requester::onNewRenewRevokeResponse(state, response);
tylerliu8e170d62020-09-30 01:31:53 -0700491 auto ca_encryption_key = ca.getCaStorage()->getRequest(readString(contentBlock.get(tlv_request_id))).m_encryptionKey;
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700492 BOOST_CHECK_EQUAL_COLLECTIONS(state.m_aesKey, state.m_aesKey + sizeof(state.m_aesKey),
tylerliu8e170d62020-09-30 01:31:53 -0700493 ca_encryption_key.value(), ca_encryption_key.value() + ca_encryption_key.value_size());
tylerliu182bc532020-09-25 01:54:45 -0700494 });
495 face.receive(*interest);
496
497 advanceClocks(time::milliseconds(20), 60);
498 BOOST_CHECK_EQUAL(count, 1);
499}
500
501BOOST_AUTO_TEST_CASE(HandleRevokeWithBadCert)
502{
503 auto identity = addIdentity(Name("/ndn"));
504 auto key = identity.getDefaultKey();
505 auto cert = key.getDefaultCertificate();
506
Zhiyi Zhang46049832020-09-28 17:08:12 -0700507 util::DummyClientFace face(io, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700508 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
tylerliu182bc532020-09-25 01:54:45 -0700509 advanceClocks(time::milliseconds(20), 60);
510
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700511 // generate a certificate
tylerliu182bc532020-09-25 01:54:45 -0700512 auto clientIdentity = m_keyChain.createIdentity("/ndn/qwerty");
513 auto clientKey = clientIdentity.getDefaultKey();
514 security::v2::Certificate clientCert;
515 clientCert.setName(Name(clientKey.getName()).append("NDNCERT").append(std::to_string(1473283247810732701)));
516 clientCert.setContentType(tlv::ContentType_Key);
517 clientCert.setFreshnessPeriod(time::hours(24));
518 clientCert.setContent(clientKey.getPublicKey().data(), clientKey.getPublicKey().size());
519 SignatureInfo signatureInfo;
520 signatureInfo.setValidityPeriod(security::ValidityPeriod(time::system_clock::now(),
Zhiyi Zhang46049832020-09-28 17:08:12 -0700521 time::system_clock::now() + time::hours(10)));
tylerliu182bc532020-09-25 01:54:45 -0700522 m_keyChain.sign(clientCert, signingByKey(clientKey.getName()).setSignatureInfo(signatureInfo));
523
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700524 CaProfile item;
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700525 item.m_caPrefix = Name("/ndn");
526 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700527 RequesterState state(m_keyChain, item, RequestType::NEW);
tylerliu182bc532020-09-25 01:54:45 -0700528
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700529 auto interest = Requester::genRevokeInterest(state, clientCert);
tylerliu182bc532020-09-25 01:54:45 -0700530
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700531 bool receiveData = false;
Zhiyi Zhang46049832020-09-28 17:08:12 -0700532 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700533 receiveData = true;
534 auto contentTlv = response.getContent();
535 contentTlv.parse();
536 BOOST_CHECK(static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv_error_code))) != ErrorCode::NO_ERROR);
tylerliu182bc532020-09-25 01:54:45 -0700537 });
538 face.receive(*interest);
539
540 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700541 BOOST_CHECK_EQUAL(receiveData, true);
tylerliu182bc532020-09-25 01:54:45 -0700542}
543
Zhiyi Zhang46049832020-09-28 17:08:12 -0700544BOOST_AUTO_TEST_SUITE_END() // TestCaModule
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800545
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700546} // namespace tests
547} // namespace ndncert
548} // namespace ndn