blob: 9ac19e5601472394dbb280c93f7f53a64f02f778 [file] [log] [blame]
Jiewen Tan870b29b2014-11-17 19:09:49 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Junxiao Shi767f35c2016-07-23 01:54:42 +00003 * Copyright (c) 2014-2016, Regents of the University of California.
Jiewen Tan870b29b2014-11-17 19:09:49 -08004 *
5 * This file is part of NDNS (Named Data Networking Domain Name Service).
6 * See AUTHORS.md for complete list of NDNS authors and contributors.
7 *
8 * NDNS is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
11 *
12 * NDNS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * NDNS, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "management-tool.hpp"
21#include "logger.hpp"
22#include "ndns-label.hpp"
23#include "ndns-tlv.hpp"
24
25#include <string>
26#include <iomanip>
27
28#include <boost/filesystem/operations.hpp>
29#include <boost/filesystem/path.hpp>
30#include <boost/algorithm/string/replace.hpp>
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -080031#include <boost/lexical_cast.hpp>
Jiewen Tan870b29b2014-11-17 19:09:49 -080032
Jiewen Tan870b29b2014-11-17 19:09:49 -080033#include <ndn-cxx/util/regex.hpp>
Jiewen Tand1dd86d2015-03-20 10:26:28 -070034#include <ndn-cxx/util/indented-stream.hpp>
Jiewen Tan870b29b2014-11-17 19:09:49 -080035#include <ndn-cxx/encoding/oid.hpp>
36#include <ndn-cxx/security/cryptopp.hpp>
Yumin Xia5dd9f2b2016-10-26 20:48:05 -070037#include <ndn-cxx/link.hpp>
Jiewen Tan870b29b2014-11-17 19:09:49 -080038
39namespace ndn {
40namespace ndns {
41
Alexander Afanasyevc7c99002015-10-09 17:27:30 -070042NDNS_LOG_INIT("ManagementTool")
Jiewen Tan870b29b2014-11-17 19:09:49 -080043
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -080044ManagementTool::ManagementTool(const std::string& dbFile, KeyChain& keyChain)
45 : m_keyChain(keyChain)
46 , m_dbMgr(dbFile)
Jiewen Tan870b29b2014-11-17 19:09:49 -080047{
48}
49
50void
51ManagementTool::createZone(const Name &zoneName,
52 const Name& parentZoneName,
53 const time::seconds& cacheTtl,
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -080054 const time::seconds& certValidity,
Jiewen Tan870b29b2014-11-17 19:09:49 -080055 const Name& kskCertName,
56 const Name& dskCertName)
57{
58 bool isRoot = zoneName == ROOT_ZONE;
59
60 //check preconditions
61 Zone zone(zoneName, cacheTtl);
62 if (m_dbMgr.find(zone)) {
63 throw Error(zoneName.toUri() + " is already presented in the NDNS db");
64 }
65
66 if (!isRoot && parentZoneName.equals(zoneName)) {
67 throw Error("Parent zone name can not be the zone itself");
68 }
69
70 if (!isRoot && !parentZoneName.isPrefixOf(zoneName)) {
71 throw Error(parentZoneName.toUri() + " is not a prefix of " + zoneName.toUri());
72 }
73
Jiewen Tan01693fd2015-03-25 20:34:45 -070074 // if dsk is provided, there is no need to check ksk
Jiewen Tan870b29b2014-11-17 19:09:49 -080075 if (dskCertName != DEFAULT_CERT) {
76 if (!matchCertificate(dskCertName, zoneName)) {
77 throw Error("Cannot verify DSK certificate");
78 }
79 }
Jiewen Tan01693fd2015-03-25 20:34:45 -070080 else if (kskCertName != DEFAULT_CERT) {
81 if (!matchCertificate(kskCertName, zoneName)) {
82 throw Error("Cannot verify KSK certificate");
83 }
84 }
Jiewen Tan870b29b2014-11-17 19:09:49 -080085
86 if (kskCertName == DEFAULT_CERT && isRoot) {
87 throw Error("Cannot generate KSK for root zone");
88 }
89
90 //first generate KSK and DSK to the keyChain system, and add DSK as default
91 NDNS_LOG_INFO("Start generating KSK and DSK and their corresponding certificates");
Jiewen Tan870b29b2014-11-17 19:09:49 -080092 Name dskName;
93 shared_ptr<IdentityCertificate> dskCert;
94 if (dskCertName == DEFAULT_CERT) {
Jiewen Tan01693fd2015-03-25 20:34:45 -070095 // if no dsk provided, then generate a dsk either signed by ksk auto generated or user provided
96 time::system_clock::TimePoint notBefore = time::system_clock::now();
97 time::system_clock::TimePoint notAfter = notBefore + certValidity;
98 shared_ptr<IdentityCertificate> kskCert;
99
100 if (kskCertName == DEFAULT_CERT) {
101 //create KSK's certificate
102 Name kskName = m_keyChain.generateRsaKeyPair(zoneName, true);
103 std::vector<CertificateSubjectDescription> kskDesc;
104 kskCert = m_keyChain.prepareUnsignedIdentityCertificate(kskName, zoneName, notBefore,
105 notAfter, kskDesc, parentZoneName);
106 kskCert->setFreshnessPeriod(cacheTtl);
107
108 m_keyChain.selfSign(*kskCert);
109 m_keyChain.addCertificate(*kskCert);
110 NDNS_LOG_INFO("Generated KSK: " << kskCert->getName());
111 }
112 else {
113 kskCert = m_keyChain.getCertificate(kskCertName);
114 }
115
Jiewen Tan870b29b2014-11-17 19:09:49 -0800116 dskName = m_keyChain.generateRsaKeyPairAsDefault(zoneName, false);
117 //create DSK's certificate
118 std::vector<CertificateSubjectDescription> dskDesc;
119 dskCert = m_keyChain.prepareUnsignedIdentityCertificate(dskName, zoneName, notBefore, notAfter,
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800120 dskDesc, zoneName);
121 dskCert->setFreshnessPeriod(cacheTtl);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800122 m_keyChain.sign(*dskCert, kskCert->getName());
123 m_keyChain.addCertificateAsKeyDefault(*dskCert);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800124 NDNS_LOG_INFO("Generated DSK: " << dskCert->getName());
Jiewen Tan870b29b2014-11-17 19:09:49 -0800125 }
126 else {
127 dskCert = m_keyChain.getCertificate(dskCertName);
128 dskName = dskCert->getPublicKeyName();
129 m_keyChain.setDefaultKeyNameForIdentity(dskName);
130 m_keyChain.setDefaultCertificateNameForKey(dskCert->getName());
131 }
132
133 //second add zone to the database
134 NDNS_LOG_INFO("Start adding new zone to data base");
135 addZone(zone);
136
137 //third create ID-cert
138 NDNS_LOG_INFO("Start creating DSK's ID-CERT");
139 addIdCert(zone, dskCert, cacheTtl);
140}
141
142void
143ManagementTool::deleteZone(const Name& zoneName)
144{
145 //check pre-conditions
146 Zone zone(zoneName);
147 if (!m_dbMgr.find(zone)) {
148 throw Error(zoneName.toUri() + " is not presented in the NDNS db");
149 }
150
151 //first remove all rrsets of this zone from local ndns database
152 std::vector<Rrset> rrsets = m_dbMgr.findRrsets(zone);
153 for (Rrset& rrset : rrsets) {
154 m_dbMgr.remove(rrset);
155 }
156
157 //second remove zone from local ndns database
158 removeZone(zone);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800159}
160
161void
162ManagementTool::exportCertificate(const Name& certName, const std::string& outFile)
163{
164 //search for the certificate, start from KeyChain then local NDNS database
165 shared_ptr<IdentityCertificate> cert;
166 if (m_keyChain.doesCertificateExist(certName)) {
167 cert = m_keyChain.getCertificate(certName);
168 }
169 else {
170 shared_ptr<Regex> regex = make_shared<Regex>("(<>*)<KEY>(<>+)<ID-CERT><>");
171 if (regex->match(certName) != true) {
172 throw Error("Certificate name is illegal");
173 }
174 Name zoneName = regex->expand("\\1");
175 Name label = regex->expand("\\2");
176
177 Zone zone(zoneName);
178 Rrset rrset(&zone);
179 rrset.setLabel(label);
180 rrset.setType(label::CERT_RR_TYPE);
181 if (m_dbMgr.find(rrset)) {
182 Data data(rrset.getData());
183 cert = make_shared<IdentityCertificate>(data);
184 }
185 else {
186 throw Error("Cannot find the cert: " + certName.toUri());
187 }
188 }
189
190 if (outFile == DEFAULT_IO) {
191 ndn::io::save(*cert, std::cout);
192 }
193 else {
194 ndn::io::save(*cert, outFile);
195 NDNS_LOG_INFO("save cert to file: " << outFile);
196 }
197}
198
199void
Yumin Xia5dd9f2b2016-10-26 20:48:05 -0700200ManagementTool::addRrset(Rrset& rrset)
Jiewen Tan870b29b2014-11-17 19:09:49 -0800201{
Jiewen Tan8cd35ea2015-03-20 00:44:23 -0700202 checkRrsetVersion(rrset);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800203 NDNS_LOG_INFO("Added " << rrset);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800204 m_dbMgr.insert(rrset);
205}
206
207void
208ManagementTool::addRrSet(const Name& zoneName,
209 const std::string& inFile,
210 const time::seconds& ttl,
Jiewen Tan74d745c2015-03-20 01:40:41 -0700211 const Name& inputDskCertName,
212 const ndn::io::IoEncoding encoding)
Jiewen Tan870b29b2014-11-17 19:09:49 -0800213{
214 //check precondition
215 Zone zone(zoneName);
216 if (!m_dbMgr.find(zone)) {
217 throw Error(zoneName.toUri() + " is not presented in the NDNS db");
218 }
219
220 Name dskName;
221 Name dskCertName = inputDskCertName;
222 if (dskCertName == DEFAULT_CERT) {
223 dskName = m_keyChain.getDefaultKeyNameForIdentity(zoneName);
224 dskCertName = m_keyChain.getDefaultCertificateNameForKey(dskName);
225 }
226 else {
227 if (!matchCertificate(dskCertName, zoneName)) {
228 throw Error("Cannot verify certificate");
229 }
230 }
231
232 if (inFile != DEFAULT_IO) {
233 boost::filesystem::path dir = boost::filesystem::path(inFile);
234 if (!boost::filesystem::exists(dir) || boost::filesystem::is_directory(dir)) {
235 throw Error("Data: " + inFile + " does not exist");
236 }
237 }
238
239 //first load the data
240 shared_ptr<Data> data;
241 if (inFile == DEFAULT_IO)
Jiewen Tan74d745c2015-03-20 01:40:41 -0700242 data = ndn::io::load<ndn::Data>(std::cin, encoding);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800243 else
Jiewen Tan74d745c2015-03-20 01:40:41 -0700244 data = ndn::io::load<ndn::Data>(inFile, encoding);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800245
Jiewen Tand2d21822015-03-19 15:37:03 -0700246 if (data == nullptr) {
Jiewen Tan74d745c2015-03-20 01:40:41 -0700247 throw Error("input does not contain a valid Data packet");
Jiewen Tand2d21822015-03-19 15:37:03 -0700248 }
249
Alexander Afanasyevfde570c2016-12-19 16:02:55 -0800250 // determine whether the data is a self-signed certificate
Jiewen Tan870b29b2014-11-17 19:09:49 -0800251 shared_ptr<Regex> regex1 = make_shared<Regex>("(<>*)<KEY>(<>+)<ID-CERT><>");
252 if (regex1->match(data->getName())) {
253 IdentityCertificate scert(*data);
254 Name keyName = scert.getPublicKeyName();
Alexander Afanasyevfde570c2016-12-19 16:02:55 -0800255 if (keyName.getPrefix(zoneName.size()) != zoneName) {
256 throw Error("the input key does not belong to the zone");
257 }
258
Jiewen Tan870b29b2014-11-17 19:09:49 -0800259 Name keyLocator = scert.getSignature().getKeyLocator().getName();
260
Alexander Afanasyevfde570c2016-12-19 16:02:55 -0800261 // if it is, extract the content and name from the data, and resign it using the dsk.
Jiewen Tan870b29b2014-11-17 19:09:49 -0800262 shared_ptr<Regex> regex2 = make_shared<Regex>("(<>*)<KEY>(<>+)<ID-CERT>");
263 BOOST_VERIFY(regex2->match(keyLocator) == true);
264 if (keyName == regex2->expand("\\1\\2")) {
Alexander Afanasyevfde570c2016-12-19 16:02:55 -0800265
266 Name canonicalName;
267 canonicalName
268 .append(zoneName)
269 .append("KEY")
270 .append(keyName.getSubName(zoneName.size(), keyName.size() - zoneName.size()))
271 .append("ID-CERT")
272 .append(data->getName().get(-1));
273
274 if (data->getName() != canonicalName) {
275 // name need to be adjusted
276 auto newData = make_shared<Data>();
277 newData->setName(canonicalName);
278 newData->setMetaInfo(data->getMetaInfo());
279 newData->setContent(data->getContent());
280 m_keyChain.sign(*newData);
281
282 data = newData;
Jiewen Tan870b29b2014-11-17 19:09:49 -0800283 }
Jiewen Tan870b29b2014-11-17 19:09:49 -0800284 }
285 }
286
287 // create response for the input data
288 Response re;
Yumin Xia6343c5b2016-10-20 15:45:50 -0700289 re.fromData(zoneName, *data);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800290 Name label = re.getRrLabel();
291 name::Component type = re.getRrType();
292
293 Rrset rrset(&zone);
294 rrset.setLabel(label);
295 rrset.setType(type);
296 if (ttl == DEFAULT_RR_TTL)
297 rrset.setTtl(zone.getTtl());
298 else
299 rrset.setTtl(ttl);
300 rrset.setVersion(re.getVersion());
301 rrset.setData(data->wireEncode());
302
Jiewen Tan8cd35ea2015-03-20 00:44:23 -0700303 checkRrsetVersion(rrset);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800304 NDNS_LOG_INFO("Added " << rrset);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800305 m_dbMgr.insert(rrset);
306}
307
308void
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800309ManagementTool::listZone(const Name& zoneName, std::ostream& os, const bool printRaw)
310{
Jiewen Tan870b29b2014-11-17 19:09:49 -0800311 Zone zone(zoneName);
312 if (!m_dbMgr.find(zone)) {
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800313 throw Error("Zone " + zoneName.toUri() + " is not found in the database");
Jiewen Tan870b29b2014-11-17 19:09:49 -0800314 }
315
316 //first output the zone name
317 os << "; Zone " << zoneName.toUri() << std::endl << std::endl;
318
319 //second output all rrsets
320 std::vector<Rrset> rrsets = m_dbMgr.findRrsets(zone);
321
322 //set width for different columns
323 size_t labelWidth = 0;
324 size_t ttlWidth = 0;
325 size_t typeWidth = 0;
326 for (Rrset& rrset : rrsets) {
327 Data data(rrset.getData());
328 Response re;
Yumin Xia6343c5b2016-10-20 15:45:50 -0700329 re.fromData(zoneName, data);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800330
331 if (rrset.getLabel().toUri().size() > labelWidth)
332 labelWidth = rrset.getLabel().toUri().size();
333
334 std::stringstream seconds;
335 seconds << rrset.getTtl().count();
336 if (seconds.str().size() > ttlWidth)
337 ttlWidth = seconds.str().size();
338
339 if (rrset.getType().toUri().size() > typeWidth)
340 typeWidth = rrset.getType().toUri().size();
341 }
342
343 //output
344 for (Rrset& rrset : rrsets) {
345 Data data(rrset.getData());
346 Response re;
Yumin Xia6343c5b2016-10-20 15:45:50 -0700347 re.fromData(zoneName, data);
Yumin Xia3c6b1fd2016-12-11 19:08:47 -0800348 int iteration = re.getContentType() == NDNS_BLOB
349 || re.getContentType() == NDNS_KEY
350 || re.getContentType() == NDNS_AUTH ? 1 : re.getRrs().size();
351
Jiewen Tan870b29b2014-11-17 19:09:49 -0800352 const std::vector<Block> &rrs = re.getRrs();
353
Yumin Xia3c6b1fd2016-12-11 19:08:47 -0800354 if (re.getContentType() != NDNS_BLOB && re.getContentType() != NDNS_KEY) {
Jiewen Tan870b29b2014-11-17 19:09:49 -0800355 os << "; rrset=" << rrset.getLabel().toUri()
356 << " type=" << rrset.getType().toUri()
357 << " version=" << rrset.getVersion().toUri()
358 << " signed-by=" << data.getSignature().getKeyLocator().getName().toUri()
359 << std::endl;
360 }
361
362 for (int i = 0; i < iteration; i++) {
363 os.setf(os.left);
364 os.width(labelWidth + 2);
365 os << rrset.getLabel().toUri();
366
367 os.width(ttlWidth + 2);
368 os << rrset.getTtl().count();
369
370 os.width(typeWidth + 2);
371 os << rrset.getType().toUri();
372
Yumin Xia3c6b1fd2016-12-11 19:08:47 -0800373 if (re.getContentType() != NDNS_BLOB && re.getContentType() != NDNS_KEY) {
Jiewen Tan870b29b2014-11-17 19:09:49 -0800374 using namespace CryptoPP;
375 if (rrset.getType() == label::TXT_RR_TYPE) {
376 os.write(reinterpret_cast<const char*>(rrs[i].value()), rrs[i].value_size());
377 os << std::endl;
378 }
379 else if (rrset.getType() == label::NS_RR_TYPE) {
Yumin Xia5dd9f2b2016-10-26 20:48:05 -0700380 BOOST_ASSERT(iteration == 1);
Yumin Xiaa484ba72016-11-10 20:40:12 -0800381 if (re.getContentType() == NDNS_AUTH) {
Yumin Xia5dd9f2b2016-10-26 20:48:05 -0700382 const std::string authStr = "NDNS-Auth";
383 os << authStr;
384 } else {
385 Link link(rrset.getData());
386 const Link::DelegationSet& ds = link.getDelegations();
387 for (const auto& i: ds) {
388 std::string str = boost::lexical_cast<std::string>(i.first)
389 + "," + i.second.toUri() + ";";
390 os << str;
391 }
392 }
Jiewen Tan870b29b2014-11-17 19:09:49 -0800393 os << std::endl;
394 }
395 else {
396 StringSource ss(rrs[i].wire(), rrs[i].size(), true,
397 new Base64Encoder(new FileSink(os), true, 64));
398 }
399 }
400 }
401
Yumin Xia3c6b1fd2016-12-11 19:08:47 -0800402 if (re.getContentType() == NDNS_BLOB || re.getContentType() == NDNS_KEY) {
Jiewen Tan870b29b2014-11-17 19:09:49 -0800403 os.width();
Yumin Xiaa484ba72016-11-10 20:40:12 -0800404 os << "; content-type=" << re.getContentType()
Jiewen Tan870b29b2014-11-17 19:09:49 -0800405 << " version=" << rrset.getVersion().toUri()
406 << " signed-by=" << data.getSignature().getKeyLocator().getName().toUri();
407 os << std::endl;
408
Yumin Xia3c6b1fd2016-12-11 19:08:47 -0800409 if (printRaw && (re.getContentType() == NDNS_BLOB
410 || re.getContentType() == NDNS_KEY)) {
Jiewen Tand1dd86d2015-03-20 10:26:28 -0700411 util::IndentedStream istream(os, "; ");
Jiewen Tan870b29b2014-11-17 19:09:49 -0800412
Jiewen Tand1dd86d2015-03-20 10:26:28 -0700413 if (re.getRrType() == label::CERT_RR_TYPE) {
414 shared_ptr<Data> data = re.toData();
415 IdentityCertificate cert(*data);
416 cert.printCertificate(istream);
417 }
418 else {
419 using namespace CryptoPP;
420 StringSource ss(re.getAppContent().wire(), re.getAppContent().size(), true,
421 new Base64Encoder(new FileSink(istream), true, 64));
Jiewen Tan870b29b2014-11-17 19:09:49 -0800422 }
Jiewen Tan870b29b2014-11-17 19:09:49 -0800423 }
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800424 os << std::endl;
Jiewen Tan870b29b2014-11-17 19:09:49 -0800425 }
426 else {
427 os << std::endl;
428 }
429 }
430}
431
432void
433ManagementTool::listAllZones(std::ostream& os) {
434 std::vector<Zone> zones = m_dbMgr.listZones();
435
436 size_t nameWidth = 0;
437 for (const Zone& zone : zones) {
438 if (zone.getName().toUri().size() > nameWidth)
439 nameWidth = zone.getName().toUri().size();
440 }
441
442 for (const Zone& zone : zones) {
443 os.setf(os.left);
444 os.width(nameWidth + 2);
445 os << zone.getName().toUri();
446
447 os << "; default-ttl=" << zone.getTtl().count();
448 os << " default-key=" << m_keyChain.getDefaultKeyNameForIdentity(zone.getName());
449 os << " default-certificate="
450 << m_keyChain.getDefaultCertificateNameForIdentity(zone.getName());
451 os << std::endl;
452 }
453}
454
455void
456ManagementTool::removeRrSet(const Name& zoneName, const Name& label, const name::Component& type)
457{
458 Zone zone(zoneName);
459 Rrset rrset(&zone);
460 rrset.setLabel(label);
461 rrset.setType(type);
462
463 if (!m_dbMgr.find(rrset)) {
464 return;
465 }
466 NDNS_LOG_INFO("Remove rrset with zone-id: " << zone.getId() << " label: " << label << " type: "
467 << type);
468 m_dbMgr.remove(rrset);
469}
470
471void
472ManagementTool::getRrSet(const Name& zoneName,
473 const Name& label,
474 const name::Component& type,
475 std::ostream& os)
476{
477 Zone zone(zoneName);
478 Rrset rrset(&zone);
479 rrset.setLabel(label);
480 rrset.setType(type);
481
482 if (!m_dbMgr.find(rrset)) {
483 os << "No record is found" << std::endl;
484 return;
485 }
486
487 using namespace CryptoPP;
488 StringSource ss(rrset.getData().wire(), rrset.getData().size(), true,
489 new Base64Encoder(new FileSink(os), true, 64));
490}
491
492void
493ManagementTool::addIdCert(Zone& zone, shared_ptr<IdentityCertificate> cert,
494 const time::seconds& ttl)
495{
496 Rrset rrset(&zone);
497 size_t size = zone.getName().size();
498 Name label = cert->getName().getSubName(size + 1, cert->getName().size() - size - 3);
499 rrset.setLabel(label);
500 rrset.setType(label::CERT_RR_TYPE);
501 rrset.setTtl(ttl);
502 rrset.setVersion(cert->getName().get(-1));
503 rrset.setData(cert->wireEncode());
504
505 if (m_dbMgr.find(rrset)) {
506 throw Error("ID-CERT with label=" + label.toUri() +
507 " is already presented in local NDNS databse");
508 }
509 NDNS_LOG_INFO("Add rrset with zone-id: " << zone.getId() << " label: " << label << " type: "
510 << label::CERT_RR_TYPE);
511 m_dbMgr.insert(rrset);
512}
513
514void
515ManagementTool::addZone(Zone& zone)
516{
517 if (m_dbMgr.find(zone)) {
518 throw Error("Zone with Name=" + zone.getName().toUri() +
519 " is already presented in local NDNS databse");
520 }
521 NDNS_LOG_INFO("Add zone with Name: " << zone.getName().toUri());
522 m_dbMgr.insert(zone);
523}
524
525void
526ManagementTool::removeZone(Zone& zone)
527{
528 if (!m_dbMgr.find(zone)) {
529 return;
530 }
531 NDNS_LOG_INFO("Remove zone with Name: " << zone.getName().toUri());
532 m_dbMgr.remove(zone);
533}
534
535bool
536ManagementTool::matchCertificate(const Name& certName, const Name& identity)
537{
538 if (!m_keyChain.doesCertificateExist(certName)) {
539 NDNS_LOG_WARN(certName.toUri() << " is not presented in KeyChain");
540 return false;
541 }
542
543 //check its public key information
544 shared_ptr<IdentityCertificate> cert = m_keyChain.getCertificate(certName);
545 Name keyName = cert->getPublicKeyName();
546
547 if (!identity.isPrefixOf(keyName) || identity.size()!=keyName.size()-1) {
548 NDNS_LOG_WARN(keyName.toUri() << " is not a key of " << identity.toUri());
549 return false;
550 }
551
Alexander Afanasyev74975e12016-08-01 14:24:03 -0700552 if (!m_keyChain.doesKeyExistInTpm(keyName, KeyClass::PRIVATE)) {
553 NDNS_LOG_WARN("Private key: " << keyName.toUri() << " is not present in KeyChain");
Jiewen Tan870b29b2014-11-17 19:09:49 -0800554 return false;
555 }
556
557 return true;
558}
559
Jiewen Tan8cd35ea2015-03-20 00:44:23 -0700560void
561ManagementTool::checkRrsetVersion(const Rrset& rrset)
562{
563 Rrset originalRrset(rrset);
564 if (m_dbMgr.find(originalRrset)) {
565 // update only if rrset has a newer version
566 if (originalRrset.getVersion() == rrset.getVersion()) {
567 throw Error("Duplicate: " + boost::lexical_cast<std::string>(originalRrset));
568 }
569 else if (originalRrset.getVersion() > rrset.getVersion()) {
570 throw Error("Newer version exists: " + boost::lexical_cast<std::string>(originalRrset));
571 }
572
573 m_dbMgr.remove(originalRrset);
574 }
575}
576
Jiewen Tan870b29b2014-11-17 19:09:49 -0800577} // namespace ndns
578} // namespace ndn