blob: ff139c674071dc37c56290c57e8b967ea73d03dd [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
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800164BOOST_AUTO_TEST_CASE(HandleNew)
165{
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700166 auto identity = addIdentity(Name("/ndn"));
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800167 auto key = identity.getDefaultKey();
168 auto cert = key.getDefaultCertificate();
169
Zhiyi Zhang22998612020-09-25 14:43:23 -0700170 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700171 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800172 advanceClocks(time::milliseconds(20), 60);
173
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700174 CaProfile item;
Suyong Won256c9062020-05-11 02:45:56 -0700175 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700176 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700177 RequesterState state(m_keyChain, item, RequestType::NEW);
178 auto interest = Requester::genNewInterest(state, Name("/ndn/zhiyi"),
179 time::system_clock::now(),
180 time::system_clock::now() + time::days(1));
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800181
182 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700183 face.onSendData.connect([&](const Data& response) {
184 count++;
185 BOOST_CHECK(security::verifySignature(response, cert));
186 auto contentBlock = response.getContent();
187 contentBlock.parse();
Suyong Won7968f7a2020-05-12 01:01:25 -0700188
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700189 BOOST_CHECK(readString(contentBlock.get(tlv_ecdh_pub)) != "");
190 BOOST_CHECK(readString(contentBlock.get(tlv_salt)) != "");
191 BOOST_CHECK(readString(contentBlock.get(tlv_request_id)) != "");
Suyong Won7968f7a2020-05-12 01:01:25 -0700192
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700193 auto challengeBlockCount = 0;
194 for (auto const& element : contentBlock.elements()) {
195 if (element.type() == tlv_challenge) {
196 challengeBlockCount++;
Suyong Won7968f7a2020-05-12 01:01:25 -0700197 }
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700198 }
Suyong Won7968f7a2020-05-12 01:01:25 -0700199
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700200 BOOST_CHECK(challengeBlockCount != 0);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700201
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700202 auto challengeList = Requester::onNewRenewRevokeResponse(state, response);
tylerliu8e170d62020-09-30 01:31:53 -0700203 auto ca_encryption_key = ca.getCaStorage()->getRequest(readString(contentBlock.get(tlv_request_id))).m_encryptionKey;
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700204 BOOST_CHECK_EQUAL_COLLECTIONS(state.m_aesKey, state.m_aesKey + sizeof(state.m_aesKey),
tylerliu8e170d62020-09-30 01:31:53 -0700205 ca_encryption_key.value(), ca_encryption_key.value() + ca_encryption_key.value_size());
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700206 });
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700207 face.receive(*interest);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800208
209 advanceClocks(time::milliseconds(20), 60);
210 BOOST_CHECK_EQUAL(count, 1);
211}
212
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700213BOOST_AUTO_TEST_CASE(HandleNewWithInvalidValidityPeriod1)
214{
215 auto identity = addIdentity(Name("/ndn"));
216 auto key = identity.getDefaultKey();
217 auto cert = key.getDefaultCertificate();
218
Zhiyi Zhang22998612020-09-25 14:43:23 -0700219 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700220 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1");
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700221 advanceClocks(time::milliseconds(20), 60);
222
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700223 CaProfile item;
Suyong Won256c9062020-05-11 02:45:56 -0700224 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700225 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700226 RequesterState state(m_keyChain, item, RequestType::NEW);
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700227 auto current_tp = time::system_clock::now();
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700228 auto interest1 = Requester::genNewInterest(state, Name("/ndn/zhiyi"), current_tp, current_tp - time::hours(1));
229 auto interest2 = Requester::genNewInterest(state, Name("/ndn/zhiyi"), current_tp, current_tp + time::days(361));
230 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 -0700231 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700232 auto contentTlv = response.getContent();
233 contentTlv.parse();
234 auto errorCode = static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv_error_code)));
235 BOOST_CHECK(errorCode != ErrorCode::NO_ERROR);
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700236 });
Zhiyi Zhang1a735bc2019-07-04 21:36:49 -0700237 face.receive(*interest1);
238 face.receive(*interest2);
239 face.receive(*interest3);
240
241 advanceClocks(time::milliseconds(20), 60);
242}
243
tylerliu0b6d0db2020-09-28 17:52:02 -0700244BOOST_AUTO_TEST_CASE(HandleNewWithLongSuffix)
245{
246 auto identity = addIdentity(Name("/ndn"));
247 auto key = identity.getDefaultKey();
248 auto cert = key.getDefaultCertificate();
249
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700250 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700251 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
tylerliu0b6d0db2020-09-28 17:52:02 -0700252 advanceClocks(time::milliseconds(20), 60);
253
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700254 CaProfile item;
tylerliu0b6d0db2020-09-28 17:52:02 -0700255 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700256 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700257 RequesterState state(m_keyChain, item, RequestType::NEW);
tylerliu0b6d0db2020-09-28 17:52:02 -0700258
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700259 auto interest1 = Requester::genNewInterest(state, Name("/ndn/a"), time::system_clock::now(),
260 time::system_clock::now() + time::days(1));
261 auto interest2 = Requester::genNewInterest(state, Name("/ndn/a/b"), time::system_clock::now(),
262 time::system_clock::now() + time::days(1));
263 auto interest3 = Requester::genNewInterest(state, Name("/ndn/a/b/c/d"), time::system_clock::now(),
264 time::system_clock::now() + time::days(1));
tylerliu0b6d0db2020-09-28 17:52:02 -0700265
tylerliu0b6d0db2020-09-28 17:52:02 -0700266 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700267 auto contentTlv = response.getContent();
268 contentTlv.parse();
269 if (interest3->getName().isPrefixOf(response.getName())) {
270 auto errorCode = static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv_error_code)));
271 BOOST_CHECK(errorCode != ErrorCode::NO_ERROR);
272 }
273 else {
274 // should successfully get responses
275 BOOST_CHECK_EXCEPTION(readNonNegativeInteger(contentTlv.get(tlv_error_code)), std::runtime_error,
276 [](const auto& e) { return true; });
277 }
tylerliu0b6d0db2020-09-28 17:52:02 -0700278 });
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700279 face.receive(*interest1);
280 face.receive(*interest2);
281 face.receive(*interest3);
tylerliu0b6d0db2020-09-28 17:52:02 -0700282 advanceClocks(time::milliseconds(20), 60);
tylerliu0b6d0db2020-09-28 17:52:02 -0700283}
284
tylerliu0b6d0db2020-09-28 17:52:02 -0700285BOOST_AUTO_TEST_CASE(HandleNewWithInvalidLength1)
286{
287 auto identity = addIdentity(Name("/ndn"));
288 auto key = identity.getDefaultKey();
289 auto cert = key.getDefaultCertificate();
290
291 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700292 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1");
tylerliu0b6d0db2020-09-28 17:52:02 -0700293 advanceClocks(time::milliseconds(20), 60);
294
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700295 CaProfile item;
tylerliu0b6d0db2020-09-28 17:52:02 -0700296 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700297 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700298 RequesterState state(m_keyChain, item, RequestType::NEW);
299
tylerliu0b6d0db2020-09-28 17:52:02 -0700300 auto current_tp = time::system_clock::now();
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700301 auto interest1 = Requester::genNewInterest(state, Name("/ndn"), current_tp, current_tp + time::days(1));
302 auto interest2 = Requester::genNewInterest(state, Name("/ndn/a/b/c/d"), current_tp, current_tp + time::days(1));
tylerliu0b6d0db2020-09-28 17:52:02 -0700303 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang01e91a32020-09-29 12:10:00 -0700304 auto contentTlv = response.getContent();
305 contentTlv.parse();
306 auto errorCode = static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv_error_code)));
307 BOOST_CHECK(errorCode != ErrorCode::NO_ERROR);
tylerliu0b6d0db2020-09-28 17:52:02 -0700308 });
309 face.receive(*interest1);
310 face.receive(*interest2);
311
312 advanceClocks(time::milliseconds(20), 60);
313}
314
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700315BOOST_AUTO_TEST_CASE(HandleChallenge)
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800316{
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700317 auto identity = addIdentity(Name("/ndn"));
318 auto key = identity.getDefaultKey();
319 auto cert = key.getDefaultCertificate();
320
Zhiyi Zhang22998612020-09-25 14:43:23 -0700321 util::DummyClientFace face(io, m_keyChain, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700322 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800323 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700324
325 // generate NEW Interest
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700326 CaProfile item;
Suyong Won256c9062020-05-11 02:45:56 -0700327 item.m_caPrefix = Name("/ndn");
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700328 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700329 RequesterState state(m_keyChain, item, RequestType::NEW);
330
331 auto newInterest = Requester::genNewInterest(state, Name("/ndn/zhiyi"), time::system_clock::now(),
332 time::system_clock::now() + time::days(1));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700333
334 // generate CHALLENGE Interest
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700335 shared_ptr<Interest> challengeInterest = nullptr;
336 shared_ptr<Interest> challengeInterest2 = nullptr;
337 shared_ptr<Interest> challengeInterest3 = nullptr;
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800338
339 int count = 0;
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700340 face.onSendData.connect([&](const Data& response) {
swa770de007bc2020-03-24 21:26:21 -0700341 if (Name("/ndn/CA/NEW").isPrefixOf(response.getName())) {
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700342 auto challengeList = Requester::onNewRenewRevokeResponse(state, response);
343 auto paramList = Requester::selectOrContinueChallenge(state, "pin");
344 challengeInterest = Requester::genChallengeInterest(state, std::move(paramList));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700345 }
swa770de007bc2020-03-24 21:26:21 -0700346 else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 0) {
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800347 count++;
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700348 BOOST_CHECK(security::verifySignature(response, cert));
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800349
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700350 Requester::onChallengeResponse(state, response);
351 BOOST_CHECK(state.m_status == Status::CHALLENGE);
352 BOOST_CHECK_EQUAL(state.m_challengeStatus, ChallengePin::NEED_CODE);
353 auto paramList = Requester::selectOrContinueChallenge(state, "pin");
354 challengeInterest2 = Requester::genChallengeInterest(state, std::move(paramList));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700355 }
swa770de007bc2020-03-24 21:26:21 -0700356 else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 1) {
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700357 count++;
358 BOOST_CHECK(security::verifySignature(response, cert));
359
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700360 Requester::onChallengeResponse(state, response);
361 BOOST_CHECK(state.m_status == Status::CHALLENGE);
362 BOOST_CHECK_EQUAL(state.m_challengeStatus, ChallengePin::WRONG_CODE);
Davide Pesavento914d05f2019-07-13 16:20:19 -0400363
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700364 auto paramList = Requester::selectOrContinueChallenge(state, "pin");
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700365 auto request = ca.getCertificateRequest(*challengeInterest2);
Zhiyi Zhanga749f442020-09-29 17:19:51 -0700366 auto secret = request.m_challengeState->m_secrets.get(ChallengePin::PARAMETER_KEY_CODE, "");
Zhiyi Zhang46049832020-09-28 17:08:12 -0700367 std::get<1>(paramList[0]) = secret;
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700368 challengeInterest3 = Requester::genChallengeInterest(state, std::move(paramList));
369 std::cout << "CHALLENGE Interest Size: " << challengeInterest3->wireEncode().size() << std::endl;
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700370 }
swa770de007bc2020-03-24 21:26:21 -0700371 else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 2) {
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700372 count++;
373 BOOST_CHECK(security::verifySignature(response, cert));
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700374 Requester::onChallengeResponse(state, response);
375 BOOST_CHECK(state.m_status == Status::SUCCESS);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700376 }
Davide Pesavento914d05f2019-07-13 16:20:19 -0400377 });
378
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700379 face.receive(*newInterest);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800380 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700381 face.receive(*challengeInterest);
382 advanceClocks(time::milliseconds(20), 60);
383 face.receive(*challengeInterest2);
384 advanceClocks(time::milliseconds(20), 60);
385 face.receive(*challengeInterest3);
386 advanceClocks(time::milliseconds(20), 60);
387 BOOST_CHECK_EQUAL(count, 3);
Zhiyi Zhang1c0bd372017-12-18 18:32:55 +0800388}
389
tylerliu182bc532020-09-25 01:54:45 -0700390BOOST_AUTO_TEST_CASE(HandleRevoke)
391{
392 auto identity = addIdentity(Name("/ndn"));
393 auto key = identity.getDefaultKey();
394 auto cert = key.getDefaultCertificate();
395
Zhiyi Zhang46049832020-09-28 17:08:12 -0700396 util::DummyClientFace face(io, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700397 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
tylerliu182bc532020-09-25 01:54:45 -0700398 advanceClocks(time::milliseconds(20), 60);
399
400 //generate a certificate
401 auto clientIdentity = m_keyChain.createIdentity("/ndn/qwerty");
402 auto clientKey = clientIdentity.getDefaultKey();
403 security::v2::Certificate clientCert;
404 clientCert.setName(Name(clientKey.getName()).append("cert-request").appendVersion());
405 clientCert.setContentType(tlv::ContentType_Key);
406 clientCert.setFreshnessPeriod(time::hours(24));
407 clientCert.setContent(clientKey.getPublicKey().data(), clientKey.getPublicKey().size());
408 SignatureInfo signatureInfo;
409 signatureInfo.setValidityPeriod(security::ValidityPeriod(time::system_clock::now(),
Zhiyi Zhang46049832020-09-28 17:08:12 -0700410 time::system_clock::now() + time::hours(10)));
tylerliu182bc532020-09-25 01:54:45 -0700411 m_keyChain.sign(clientCert, signingByKey(clientKey.getName()).setSignatureInfo(signatureInfo));
tylerliu8e170d62020-09-30 01:31:53 -0700412 RequestState certRequest(Name("/ndn"), "122", RequestType::NEW, Status::SUCCESS, clientCert, makeEmptyBlock(tlv::ContentType_Key));
tylerliu182bc532020-09-25 01:54:45 -0700413 auto issuedCert = ca.issueCertificate(certRequest);
414
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700415 CaProfile item;
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700416 item.m_caPrefix = Name("/ndn");
417 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700418 RequesterState state(m_keyChain, item, RequestType::REVOKE);
tylerliu182bc532020-09-25 01:54:45 -0700419
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700420 auto interest = Requester::genRevokeInterest(state, issuedCert);
tylerliu182bc532020-09-25 01:54:45 -0700421
422 int count = 0;
Zhiyi Zhang46049832020-09-28 17:08:12 -0700423 face.onSendData.connect([&](const Data& response) {
tylerliu182bc532020-09-25 01:54:45 -0700424 count++;
425 BOOST_CHECK(security::verifySignature(response, cert));
426 auto contentBlock = response.getContent();
427 contentBlock.parse();
428
429 BOOST_CHECK(readString(contentBlock.get(tlv_ecdh_pub)) != "");
430 BOOST_CHECK(readString(contentBlock.get(tlv_salt)) != "");
431 BOOST_CHECK(readString(contentBlock.get(tlv_request_id)) != "");
432
433 auto challengeBlockCount = 0;
434 for (auto const& element : contentBlock.elements()) {
Zhiyi Zhang46049832020-09-28 17:08:12 -0700435 if (element.type() == tlv_challenge) {
436 challengeBlockCount++;
437 }
tylerliu182bc532020-09-25 01:54:45 -0700438 }
439
440 BOOST_CHECK(challengeBlockCount != 0);
441
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700442 auto challengeList = Requester::onNewRenewRevokeResponse(state, response);
tylerliu8e170d62020-09-30 01:31:53 -0700443 auto ca_encryption_key = ca.getCaStorage()->getRequest(readString(contentBlock.get(tlv_request_id))).m_encryptionKey;
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700444 BOOST_CHECK_EQUAL_COLLECTIONS(state.m_aesKey, state.m_aesKey + sizeof(state.m_aesKey),
tylerliu8e170d62020-09-30 01:31:53 -0700445 ca_encryption_key.value(), ca_encryption_key.value() + ca_encryption_key.value_size());
tylerliu182bc532020-09-25 01:54:45 -0700446 });
447 face.receive(*interest);
448
449 advanceClocks(time::milliseconds(20), 60);
450 BOOST_CHECK_EQUAL(count, 1);
451}
452
453BOOST_AUTO_TEST_CASE(HandleRevokeWithBadCert)
454{
455 auto identity = addIdentity(Name("/ndn"));
456 auto key = identity.getDefaultKey();
457 auto cert = key.getDefaultCertificate();
458
Zhiyi Zhang46049832020-09-28 17:08:12 -0700459 util::DummyClientFace face(io, {true, true});
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700460 CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
tylerliu182bc532020-09-25 01:54:45 -0700461 advanceClocks(time::milliseconds(20), 60);
462
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700463 // generate a certificate
tylerliu182bc532020-09-25 01:54:45 -0700464 auto clientIdentity = m_keyChain.createIdentity("/ndn/qwerty");
465 auto clientKey = clientIdentity.getDefaultKey();
466 security::v2::Certificate clientCert;
467 clientCert.setName(Name(clientKey.getName()).append("NDNCERT").append(std::to_string(1473283247810732701)));
468 clientCert.setContentType(tlv::ContentType_Key);
469 clientCert.setFreshnessPeriod(time::hours(24));
470 clientCert.setContent(clientKey.getPublicKey().data(), clientKey.getPublicKey().size());
471 SignatureInfo signatureInfo;
472 signatureInfo.setValidityPeriod(security::ValidityPeriod(time::system_clock::now(),
Zhiyi Zhang46049832020-09-28 17:08:12 -0700473 time::system_clock::now() + time::hours(10)));
tylerliu182bc532020-09-25 01:54:45 -0700474 m_keyChain.sign(clientCert, signingByKey(clientKey.getName()).setSignatureInfo(signatureInfo));
475
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700476 CaProfile item;
Zhiyi Zhang9829da92020-09-30 16:19:34 -0700477 item.m_caPrefix = Name("/ndn");
478 item.m_cert = std::make_shared<security::v2::Certificate>(cert);
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700479 RequesterState state(m_keyChain, item, RequestType::NEW);
tylerliu182bc532020-09-25 01:54:45 -0700480
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700481 auto interest = Requester::genRevokeInterest(state, clientCert);
tylerliu182bc532020-09-25 01:54:45 -0700482
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700483 bool receiveData = false;
Zhiyi Zhang46049832020-09-28 17:08:12 -0700484 face.onSendData.connect([&](const Data& response) {
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700485 receiveData = true;
486 auto contentTlv = response.getContent();
487 contentTlv.parse();
488 BOOST_CHECK(static_cast<ErrorCode>(readNonNegativeInteger(contentTlv.get(tlv_error_code))) != ErrorCode::NO_ERROR);
tylerliu182bc532020-09-25 01:54:45 -0700489 });
490 face.receive(*interest);
491
492 advanceClocks(time::milliseconds(20), 60);
Zhiyi Zhang3e8ca252020-09-30 17:18:38 -0700493 BOOST_CHECK_EQUAL(receiveData, true);
tylerliu182bc532020-09-25 01:54:45 -0700494}
495
Zhiyi Zhang46049832020-09-28 17:08:12 -0700496BOOST_AUTO_TEST_SUITE_END() // TestCaModule
Zhiyi Zhangf5246c42017-01-26 09:39:20 -0800497
Zhiyi Zhangfc1678a2020-05-12 16:52:14 -0700498} // namespace tests
499} // namespace ndncert
500} // namespace ndn