blob: a53b0aabe0e6ed3991aff7b9f7edb8e121efb0a6 [file] [log] [blame]
Jiewen Tan870b29b2014-11-17 19:09:49 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014, Regents of the University of California.
4 *
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>
37
38namespace ndn {
39namespace ndns {
40
41NDNS_LOG_INIT("ManagementTool");
42
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -080043ManagementTool::ManagementTool(const std::string& dbFile, KeyChain& keyChain)
44 : m_keyChain(keyChain)
45 , m_dbMgr(dbFile)
Jiewen Tan870b29b2014-11-17 19:09:49 -080046{
47}
48
49void
50ManagementTool::createZone(const Name &zoneName,
51 const Name& parentZoneName,
52 const time::seconds& cacheTtl,
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -080053 const time::seconds& certValidity,
Jiewen Tan870b29b2014-11-17 19:09:49 -080054 const Name& kskCertName,
55 const Name& dskCertName)
56{
57 bool isRoot = zoneName == ROOT_ZONE;
58
59 //check preconditions
60 Zone zone(zoneName, cacheTtl);
61 if (m_dbMgr.find(zone)) {
62 throw Error(zoneName.toUri() + " is already presented in the NDNS db");
63 }
64
65 if (!isRoot && parentZoneName.equals(zoneName)) {
66 throw Error("Parent zone name can not be the zone itself");
67 }
68
69 if (!isRoot && !parentZoneName.isPrefixOf(zoneName)) {
70 throw Error(parentZoneName.toUri() + " is not a prefix of " + zoneName.toUri());
71 }
72
73 if (kskCertName != DEFAULT_CERT) {
74 if (!matchCertificate(kskCertName, zoneName)) {
75 throw Error("Cannot verify KSK certificate");
76 }
77 }
78
79 if (dskCertName != DEFAULT_CERT) {
80 if (!matchCertificate(dskCertName, zoneName)) {
81 throw Error("Cannot verify DSK certificate");
82 }
83 }
84
85 if (kskCertName == DEFAULT_CERT && isRoot) {
86 throw Error("Cannot generate KSK for root zone");
87 }
88
89 //first generate KSK and DSK to the keyChain system, and add DSK as default
90 NDNS_LOG_INFO("Start generating KSK and DSK and their corresponding certificates");
91 time::system_clock::TimePoint notBefore = time::system_clock::now();
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -080092 time::system_clock::TimePoint notAfter = notBefore + certValidity;
Jiewen Tan870b29b2014-11-17 19:09:49 -080093 shared_ptr<IdentityCertificate> kskCert;
94
95 if (kskCertName == DEFAULT_CERT) {
96 //create KSK's certificate
97 Name kskName = m_keyChain.generateRsaKeyPair(zoneName, true);
98 std::vector<CertificateSubjectDescription> kskDesc;
99 kskCert = m_keyChain.prepareUnsignedIdentityCertificate(kskName, zoneName, notBefore, notAfter,
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800100 kskDesc, parentZoneName);
101 kskCert->setFreshnessPeriod(cacheTtl);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800102
103 m_keyChain.selfSign(*kskCert);
104 m_keyChain.addCertificate(*kskCert);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800105 NDNS_LOG_INFO("Generated KSK: " << kskCert->getName());
Jiewen Tan870b29b2014-11-17 19:09:49 -0800106 }
107 else {
108 kskCert = m_keyChain.getCertificate(kskCertName);
109 }
110
111 Name dskName;
112 shared_ptr<IdentityCertificate> dskCert;
113 if (dskCertName == DEFAULT_CERT) {
114 dskName = m_keyChain.generateRsaKeyPairAsDefault(zoneName, false);
115 //create DSK's certificate
116 std::vector<CertificateSubjectDescription> dskDesc;
117 dskCert = m_keyChain.prepareUnsignedIdentityCertificate(dskName, zoneName, notBefore, notAfter,
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800118 dskDesc, zoneName);
119 dskCert->setFreshnessPeriod(cacheTtl);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800120 m_keyChain.sign(*dskCert, kskCert->getName());
121 m_keyChain.addCertificateAsKeyDefault(*dskCert);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800122 NDNS_LOG_INFO("Generated DSK: " << dskCert->getName());
Jiewen Tan870b29b2014-11-17 19:09:49 -0800123 }
124 else {
125 dskCert = m_keyChain.getCertificate(dskCertName);
126 dskName = dskCert->getPublicKeyName();
127 m_keyChain.setDefaultKeyNameForIdentity(dskName);
128 m_keyChain.setDefaultCertificateNameForKey(dskCert->getName());
129 }
130
131 //second add zone to the database
132 NDNS_LOG_INFO("Start adding new zone to data base");
133 addZone(zone);
134
135 //third create ID-cert
136 NDNS_LOG_INFO("Start creating DSK's ID-CERT");
137 addIdCert(zone, dskCert, cacheTtl);
138}
139
140void
141ManagementTool::deleteZone(const Name& zoneName)
142{
143 //check pre-conditions
144 Zone zone(zoneName);
145 if (!m_dbMgr.find(zone)) {
146 throw Error(zoneName.toUri() + " is not presented in the NDNS db");
147 }
148
149 //first remove all rrsets of this zone from local ndns database
150 std::vector<Rrset> rrsets = m_dbMgr.findRrsets(zone);
151 for (Rrset& rrset : rrsets) {
152 m_dbMgr.remove(rrset);
153 }
154
155 //second remove zone from local ndns database
156 removeZone(zone);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800157}
158
159void
160ManagementTool::exportCertificate(const Name& certName, const std::string& outFile)
161{
162 //search for the certificate, start from KeyChain then local NDNS database
163 shared_ptr<IdentityCertificate> cert;
164 if (m_keyChain.doesCertificateExist(certName)) {
165 cert = m_keyChain.getCertificate(certName);
166 }
167 else {
168 shared_ptr<Regex> regex = make_shared<Regex>("(<>*)<KEY>(<>+)<ID-CERT><>");
169 if (regex->match(certName) != true) {
170 throw Error("Certificate name is illegal");
171 }
172 Name zoneName = regex->expand("\\1");
173 Name label = regex->expand("\\2");
174
175 Zone zone(zoneName);
176 Rrset rrset(&zone);
177 rrset.setLabel(label);
178 rrset.setType(label::CERT_RR_TYPE);
179 if (m_dbMgr.find(rrset)) {
180 Data data(rrset.getData());
181 cert = make_shared<IdentityCertificate>(data);
182 }
183 else {
184 throw Error("Cannot find the cert: " + certName.toUri());
185 }
186 }
187
188 if (outFile == DEFAULT_IO) {
189 ndn::io::save(*cert, std::cout);
190 }
191 else {
192 ndn::io::save(*cert, outFile);
193 NDNS_LOG_INFO("save cert to file: " << outFile);
194 }
195}
196
197void
198ManagementTool::addRrSet(const Name& zoneName,
199 const Name& label,
200 const name::Component& type,
201 NdnsType ndnsType,
202 const uint64_t version,
203 const std::vector<std::string>& contents,
204 const Name& inputDskCertName,
205 const time::seconds& ttl)
206{
207 // check pre-condition
208 Zone zone(zoneName);
209 if (!m_dbMgr.find(zone)) {
210 throw Error(zoneName.toUri() + " is not presented in the NDNS db");
211 }
212
213 if (ndnsType == NDNS_UNKNOWN) {
214 throw Error("The ndns type is unknown");
215 }
216
217 if (type == label::CERT_RR_TYPE) {
218 throw Error("It cannot handle ID-CERT rrset type");
219 }
220
221 // check strange rr type and ndns type combination
222 if (type == label::NS_RR_TYPE && ndnsType == NDNS_RAW) {
223 throw Error("NS cannot be of the type NDNS_RAW");
224 }
225
226 if (type == label::TXT_RR_TYPE && ndnsType != NDNS_RESP) {
227 throw Error("TXT cannot be of the type NDNS_RAW or NDNS_AUTH");
228 }
229
230 if (ndnsType == NDNS_RAW && contents.size() != 1) {
231 throw Error("NDNS_RAW must contain a single content element");
232 }
233
234 Name dskName;
235 Name dskCertName = inputDskCertName;
236 if (dskCertName == DEFAULT_CERT) {
237 dskName = m_keyChain.getDefaultKeyNameForIdentity(zoneName);
238 dskCertName = m_keyChain.getDefaultCertificateNameForKey(dskName);
239 }
240 else {
241 if (!matchCertificate(dskCertName, zoneName)) {
242 throw Error("Cannot verify certificate");
243 }
244 }
245
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800246 time::seconds actualTtl = ttl;
247 if (ttl == DEFAULT_RR_TTL)
248 actualTtl = zone.getTtl();
249
Jiewen Tan870b29b2014-11-17 19:09:49 -0800250 // set rrset
251 Rrset rrset(&zone);
252 rrset.setLabel(label);
253 rrset.setType(type);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800254 rrset.setTtl(actualTtl);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800255
256 // set response
257 Response re;
258 re.setZone(zoneName);
259 re.setQueryType(label::NDNS_ITERATIVE_QUERY);
260 re.setRrLabel(label);
261 re.setRrType(type);
262 re.setNdnsType(ndnsType);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800263 re.setFreshnessPeriod(actualTtl);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800264
265 //set content according to ndns type
266 if (ndnsType == NDNS_RAW) {
267 Block tmp = ndn::dataBlock(ndn::tlv::Content, contents[0].c_str(), contents[0].length());
268 re.setAppContent(tmp);
269 }
270 else if (ndnsType != NDNS_AUTH) {
271 if (contents.empty()) {
272 re.addRr("");
273 }
274 else {
275 for (const auto& item : contents) {
276 re.addRr(item);
277 }
278 }
279 }
280
Jiewen Tan870b29b2014-11-17 19:09:49 -0800281 if (version != VERSION_USE_UNIX_TIMESTAMP) {
282 name::Component tmp = name::Component::fromVersion(version);
283 re.setVersion(tmp);
284 }
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800285 shared_ptr<Data> data = re.toData();
Jiewen Tan870b29b2014-11-17 19:09:49 -0800286 m_keyChain.sign(*data, dskCertName);
287
288 rrset.setVersion(re.getVersion());
289 rrset.setData(data->wireEncode());
290
Jiewen Tan8cd35ea2015-03-20 00:44:23 -0700291 checkRrsetVersion(rrset);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800292 NDNS_LOG_INFO("Added " << rrset);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800293 m_dbMgr.insert(rrset);
294}
295
296void
297ManagementTool::addRrSet(const Name& zoneName,
298 const std::string& inFile,
299 const time::seconds& ttl,
Jiewen Tan74d745c2015-03-20 01:40:41 -0700300 const Name& inputDskCertName,
301 const ndn::io::IoEncoding encoding)
Jiewen Tan870b29b2014-11-17 19:09:49 -0800302{
303 //check precondition
304 Zone zone(zoneName);
305 if (!m_dbMgr.find(zone)) {
306 throw Error(zoneName.toUri() + " is not presented in the NDNS db");
307 }
308
309 Name dskName;
310 Name dskCertName = inputDskCertName;
311 if (dskCertName == DEFAULT_CERT) {
312 dskName = m_keyChain.getDefaultKeyNameForIdentity(zoneName);
313 dskCertName = m_keyChain.getDefaultCertificateNameForKey(dskName);
314 }
315 else {
316 if (!matchCertificate(dskCertName, zoneName)) {
317 throw Error("Cannot verify certificate");
318 }
319 }
320
321 if (inFile != DEFAULT_IO) {
322 boost::filesystem::path dir = boost::filesystem::path(inFile);
323 if (!boost::filesystem::exists(dir) || boost::filesystem::is_directory(dir)) {
324 throw Error("Data: " + inFile + " does not exist");
325 }
326 }
327
328 //first load the data
329 shared_ptr<Data> data;
330 if (inFile == DEFAULT_IO)
Jiewen Tan74d745c2015-03-20 01:40:41 -0700331 data = ndn::io::load<ndn::Data>(std::cin, encoding);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800332 else
Jiewen Tan74d745c2015-03-20 01:40:41 -0700333 data = ndn::io::load<ndn::Data>(inFile, encoding);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800334
Jiewen Tand2d21822015-03-19 15:37:03 -0700335 if (data == nullptr) {
Jiewen Tan74d745c2015-03-20 01:40:41 -0700336 throw Error("input does not contain a valid Data packet");
Jiewen Tand2d21822015-03-19 15:37:03 -0700337 }
338
Jiewen Tan870b29b2014-11-17 19:09:49 -0800339 //determine whether the data is a self-signed certificate
340 shared_ptr<Regex> regex1 = make_shared<Regex>("(<>*)<KEY>(<>+)<ID-CERT><>");
341 if (regex1->match(data->getName())) {
342 IdentityCertificate scert(*data);
343 Name keyName = scert.getPublicKeyName();
344 Name keyLocator = scert.getSignature().getKeyLocator().getName();
345
346 //if it is, extract the content and name from the data, and resign it using the dsk.
347 shared_ptr<Regex> regex2 = make_shared<Regex>("(<>*)<KEY>(<>+)<ID-CERT>");
348 BOOST_VERIFY(regex2->match(keyLocator) == true);
349 if (keyName == regex2->expand("\\1\\2")) {
350 shared_ptr<Data> pre = data;
351 Name name = pre->getName();
352 //check whether the name is legal or not. if not converting it to a legal name
353 if (zoneName != regex1->expand("\\1")) {
354 Name comp1 = regex1->expand("\\1").getSubName(zoneName.size());
355 Name comp2 = regex1->expand("\\2");
356 name = zoneName;
357 name.append("KEY");
358 name.append(comp1);
359 name.append(comp2);
360 name.append("ID-CERT");
361 name.append(pre->getName().get(-1));
362 }
363
364 data = make_shared<Data>();
365 data->setName(name);
366 data->setContent(pre->getContent());
367
368 m_keyChain.sign(*data, dskCertName);
369 }
370 }
371
372 // create response for the input data
373 Response re;
374 Name hint;
375 re.fromData(hint, zoneName, *data);
376 Name label = re.getRrLabel();
377 name::Component type = re.getRrType();
378
379 Rrset rrset(&zone);
380 rrset.setLabel(label);
381 rrset.setType(type);
382 if (ttl == DEFAULT_RR_TTL)
383 rrset.setTtl(zone.getTtl());
384 else
385 rrset.setTtl(ttl);
386 rrset.setVersion(re.getVersion());
387 rrset.setData(data->wireEncode());
388
Jiewen Tan8cd35ea2015-03-20 00:44:23 -0700389 checkRrsetVersion(rrset);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800390 NDNS_LOG_INFO("Added " << rrset);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800391 m_dbMgr.insert(rrset);
392}
393
394void
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800395ManagementTool::listZone(const Name& zoneName, std::ostream& os, const bool printRaw)
396{
Jiewen Tan870b29b2014-11-17 19:09:49 -0800397 Zone zone(zoneName);
398 if (!m_dbMgr.find(zone)) {
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800399 throw Error("Zone " + zoneName.toUri() + " is not found in the database");
Jiewen Tan870b29b2014-11-17 19:09:49 -0800400 }
401
402 //first output the zone name
403 os << "; Zone " << zoneName.toUri() << std::endl << std::endl;
404
405 //second output all rrsets
406 std::vector<Rrset> rrsets = m_dbMgr.findRrsets(zone);
407
408 //set width for different columns
409 size_t labelWidth = 0;
410 size_t ttlWidth = 0;
411 size_t typeWidth = 0;
412 for (Rrset& rrset : rrsets) {
413 Data data(rrset.getData());
414 Response re;
415 Name hint;
416 re.fromData(hint, zoneName, data);
417
418 if (rrset.getLabel().toUri().size() > labelWidth)
419 labelWidth = rrset.getLabel().toUri().size();
420
421 std::stringstream seconds;
422 seconds << rrset.getTtl().count();
423 if (seconds.str().size() > ttlWidth)
424 ttlWidth = seconds.str().size();
425
426 if (rrset.getType().toUri().size() > typeWidth)
427 typeWidth = rrset.getType().toUri().size();
428 }
429
430 //output
431 for (Rrset& rrset : rrsets) {
432 Data data(rrset.getData());
433 Response re;
434 Name hint;
435 re.fromData(hint, zoneName, data);
436 int iteration = re.getNdnsType() == NDNS_RAW || re.getNdnsType() == NDNS_AUTH ?
437 1 : re.getRrs().size();
438 const std::vector<Block> &rrs = re.getRrs();
439
440 if (re.getNdnsType() != NDNS_RAW && re.getNdnsType() != NDNS_AUTH) {
441 os << "; rrset=" << rrset.getLabel().toUri()
442 << " type=" << rrset.getType().toUri()
443 << " version=" << rrset.getVersion().toUri()
444 << " signed-by=" << data.getSignature().getKeyLocator().getName().toUri()
445 << std::endl;
446 }
447
448 for (int i = 0; i < iteration; i++) {
449 os.setf(os.left);
450 os.width(labelWidth + 2);
451 os << rrset.getLabel().toUri();
452
453 os.width(ttlWidth + 2);
454 os << rrset.getTtl().count();
455
456 os.width(typeWidth + 2);
457 os << rrset.getType().toUri();
458
459 if (re.getNdnsType() != NDNS_RAW && re.getNdnsType() != NDNS_AUTH) {
460 using namespace CryptoPP;
461 if (rrset.getType() == label::TXT_RR_TYPE) {
462 os.write(reinterpret_cast<const char*>(rrs[i].value()), rrs[i].value_size());
463 os << std::endl;
464 }
465 else if (rrset.getType() == label::NS_RR_TYPE) {
466 //TODO output the NS data once we have it
467 os << std::endl;
468 }
469 else {
470 StringSource ss(rrs[i].wire(), rrs[i].size(), true,
471 new Base64Encoder(new FileSink(os), true, 64));
472 }
473 }
474 }
475
476 if (re.getNdnsType() == NDNS_RAW || re.getNdnsType() == NDNS_AUTH) {
477 os.width();
478 os << "; content-type=" << re.getNdnsType()
479 << " version=" << rrset.getVersion().toUri()
480 << " signed-by=" << data.getSignature().getKeyLocator().getName().toUri();
481 os << std::endl;
482
483 if (printRaw && re.getNdnsType() == NDNS_RAW) {
Jiewen Tand1dd86d2015-03-20 10:26:28 -0700484 util::IndentedStream istream(os, "; ");
Jiewen Tan870b29b2014-11-17 19:09:49 -0800485
Jiewen Tand1dd86d2015-03-20 10:26:28 -0700486 if (re.getRrType() == label::CERT_RR_TYPE) {
487 shared_ptr<Data> data = re.toData();
488 IdentityCertificate cert(*data);
489 cert.printCertificate(istream);
490 }
491 else {
492 using namespace CryptoPP;
493 StringSource ss(re.getAppContent().wire(), re.getAppContent().size(), true,
494 new Base64Encoder(new FileSink(istream), true, 64));
Jiewen Tan870b29b2014-11-17 19:09:49 -0800495 }
Jiewen Tan870b29b2014-11-17 19:09:49 -0800496 }
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800497 os << std::endl;
Jiewen Tan870b29b2014-11-17 19:09:49 -0800498 }
499 else {
500 os << std::endl;
501 }
502 }
503}
504
505void
506ManagementTool::listAllZones(std::ostream& os) {
507 std::vector<Zone> zones = m_dbMgr.listZones();
508
509 size_t nameWidth = 0;
510 for (const Zone& zone : zones) {
511 if (zone.getName().toUri().size() > nameWidth)
512 nameWidth = zone.getName().toUri().size();
513 }
514
515 for (const Zone& zone : zones) {
516 os.setf(os.left);
517 os.width(nameWidth + 2);
518 os << zone.getName().toUri();
519
520 os << "; default-ttl=" << zone.getTtl().count();
521 os << " default-key=" << m_keyChain.getDefaultKeyNameForIdentity(zone.getName());
522 os << " default-certificate="
523 << m_keyChain.getDefaultCertificateNameForIdentity(zone.getName());
524 os << std::endl;
525 }
526}
527
528void
529ManagementTool::removeRrSet(const Name& zoneName, const Name& label, const name::Component& type)
530{
531 Zone zone(zoneName);
532 Rrset rrset(&zone);
533 rrset.setLabel(label);
534 rrset.setType(type);
535
536 if (!m_dbMgr.find(rrset)) {
537 return;
538 }
539 NDNS_LOG_INFO("Remove rrset with zone-id: " << zone.getId() << " label: " << label << " type: "
540 << type);
541 m_dbMgr.remove(rrset);
542}
543
544void
545ManagementTool::getRrSet(const Name& zoneName,
546 const Name& label,
547 const name::Component& type,
548 std::ostream& os)
549{
550 Zone zone(zoneName);
551 Rrset rrset(&zone);
552 rrset.setLabel(label);
553 rrset.setType(type);
554
555 if (!m_dbMgr.find(rrset)) {
556 os << "No record is found" << std::endl;
557 return;
558 }
559
560 using namespace CryptoPP;
561 StringSource ss(rrset.getData().wire(), rrset.getData().size(), true,
562 new Base64Encoder(new FileSink(os), true, 64));
563}
564
565void
566ManagementTool::addIdCert(Zone& zone, shared_ptr<IdentityCertificate> cert,
567 const time::seconds& ttl)
568{
569 Rrset rrset(&zone);
570 size_t size = zone.getName().size();
571 Name label = cert->getName().getSubName(size + 1, cert->getName().size() - size - 3);
572 rrset.setLabel(label);
573 rrset.setType(label::CERT_RR_TYPE);
574 rrset.setTtl(ttl);
575 rrset.setVersion(cert->getName().get(-1));
576 rrset.setData(cert->wireEncode());
577
578 if (m_dbMgr.find(rrset)) {
579 throw Error("ID-CERT with label=" + label.toUri() +
580 " is already presented in local NDNS databse");
581 }
582 NDNS_LOG_INFO("Add rrset with zone-id: " << zone.getId() << " label: " << label << " type: "
583 << label::CERT_RR_TYPE);
584 m_dbMgr.insert(rrset);
585}
586
587void
588ManagementTool::addZone(Zone& zone)
589{
590 if (m_dbMgr.find(zone)) {
591 throw Error("Zone with Name=" + zone.getName().toUri() +
592 " is already presented in local NDNS databse");
593 }
594 NDNS_LOG_INFO("Add zone with Name: " << zone.getName().toUri());
595 m_dbMgr.insert(zone);
596}
597
598void
599ManagementTool::removeZone(Zone& zone)
600{
601 if (!m_dbMgr.find(zone)) {
602 return;
603 }
604 NDNS_LOG_INFO("Remove zone with Name: " << zone.getName().toUri());
605 m_dbMgr.remove(zone);
606}
607
608bool
609ManagementTool::matchCertificate(const Name& certName, const Name& identity)
610{
611 if (!m_keyChain.doesCertificateExist(certName)) {
612 NDNS_LOG_WARN(certName.toUri() << " is not presented in KeyChain");
613 return false;
614 }
615
616 //check its public key information
617 shared_ptr<IdentityCertificate> cert = m_keyChain.getCertificate(certName);
618 Name keyName = cert->getPublicKeyName();
619
620 if (!identity.isPrefixOf(keyName) || identity.size()!=keyName.size()-1) {
621 NDNS_LOG_WARN(keyName.toUri() << " is not a key of " << identity.toUri());
622 return false;
623 }
624
625 if (!m_keyChain.doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE)) {
626 NDNS_LOG_WARN("Private key: " << keyName.toUri() << " is not presented in KeyChain");
627 return false;
628 }
629
630 return true;
631}
632
Jiewen Tan8cd35ea2015-03-20 00:44:23 -0700633void
634ManagementTool::checkRrsetVersion(const Rrset& rrset)
635{
636 Rrset originalRrset(rrset);
637 if (m_dbMgr.find(originalRrset)) {
638 // update only if rrset has a newer version
639 if (originalRrset.getVersion() == rrset.getVersion()) {
640 throw Error("Duplicate: " + boost::lexical_cast<std::string>(originalRrset));
641 }
642 else if (originalRrset.getVersion() > rrset.getVersion()) {
643 throw Error("Newer version exists: " + boost::lexical_cast<std::string>(originalRrset));
644 }
645
646 m_dbMgr.remove(originalRrset);
647 }
648}
649
Jiewen Tan870b29b2014-11-17 19:09:49 -0800650} // namespace ndns
651} // namespace ndn