blob: a345d44c03fe6ce47c01a5529c79f417e1441bd7 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi476200b2017-10-05 12:16:27 +00002/*
Alexander Afanasyev634a62b2018-06-15 16:55:26 -04003 * Copyright (c) 2013-2018 Regents of the University of California.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library 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 Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
Yingdi Yu8d7468f2014-02-21 14:49:45 -080020 */
21
Alexander Afanasyev82c359c2017-01-04 14:48:07 -080022#include "ndnsec.hpp"
Alexander Afanasyevd7db8bf2015-01-04 15:31:02 -080023#include "util.hpp"
Yingdi Yu8d7468f2014-02-21 14:49:45 -080024
Alexander Afanasyev82c359c2017-01-04 14:48:07 -080025namespace ndn {
26namespace ndnsec {
27
Yingdi Yub61f5402014-02-26 17:46:11 -080028int
Yingdi Yu8d7468f2014-02-21 14:49:45 -080029ndnsec_export(int argc, char** argv)
30{
Yingdi Yu8d7468f2014-02-21 14:49:45 -080031 namespace po = boost::program_options;
32
Alexander Afanasyev35109a12017-01-04 15:39:06 -080033 Name identityName;
Yingdi Yu8d7468f2014-02-21 14:49:45 -080034 std::string output;
35 std::string exportPassword;
36
Alexander Afanasyev634a62b2018-06-15 16:55:26 -040037 po::options_description description("General Usage\n"
38 " ndnsec export [-h] [-o output] [-P passphrase] identity \n"
39 "General options");
Yingdi Yub61f5402014-02-26 17:46:11 -080040 description.add_options()
Yingdi Yu8d7468f2014-02-21 14:49:45 -080041 ("help,h", "Produce help message")
42 ("output,o", po::value<std::string>(&output), "(Optional) output file, stdout if not specified")
Alexander Afanasyev35109a12017-01-04 15:39:06 -080043 ("identity,i", po::value<Name>(&identityName), "Identity to export")
Alexander Afanasyev634a62b2018-06-15 16:55:26 -040044 ("password,P", po::value<std::string>(&exportPassword), "Passphrase (will prompt if empty or not specified)")
Yingdi Yu8d7468f2014-02-21 14:49:45 -080045 ;
46
47 po::positional_options_description p;
48 p.add("identity", 1);
49
50 po::variables_map vm;
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070051 try {
Alexander Afanasyev82c359c2017-01-04 14:48:07 -080052 po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(), vm);
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070053 po::notify(vm);
54 }
55 catch (const std::exception& e) {
56 std::cerr << "ERROR: " << e.what() << std::endl;
57 std::cerr << description << std::endl;
58 return 1;
59 }
Yingdi Yu8d7468f2014-02-21 14:49:45 -080060
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070061 if (vm.count("help") != 0) {
62 std::cerr << description << std::endl;
63 return 0;
64 }
Yingdi Yu8d7468f2014-02-21 14:49:45 -080065
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070066 if (vm.count("identity") == 0) {
67 std::cerr << "ERROR: identity must be specified" << std::endl;
68 std::cerr << description << std::endl;
69 return 1;
70 }
Yingdi Yu64c3fb42014-02-26 17:30:04 -080071
Yingdi Yub61f5402014-02-26 17:46:11 -080072 if (vm.count("output") == 0)
Yingdi Yu8d7468f2014-02-21 14:49:45 -080073 output = "-";
74
Alexander Afanasyev35109a12017-01-04 15:39:06 -080075 try {
Alexander Afanasyev634a62b2018-06-15 16:55:26 -040076 if (exportPassword.empty()) {
77 int count = 3;
78 while (!getPassword(exportPassword, "Passphrase for the private key: ")) {
79 count--;
80 if (count <= 0) {
81 std::cerr << "ERROR: invalid password" << std::endl;
82 memset(const_cast<char*>(exportPassword.c_str()), 0, exportPassword.size());
83 return 1;
84 }
Alexander Afanasyev35109a12017-01-04 15:39:06 -080085 }
86 }
87
88 security::v2::KeyChain keyChain;
89 security::Identity id = keyChain.getPib().getIdentity(identityName);
90
91 // @TODO export all certificates, selected key pair, selected certificate
92 shared_ptr<security::SafeBag> safeBag = keyChain.exportSafeBag(id.getDefaultKey().getDefaultCertificate(),
93 exportPassword.c_str(), exportPassword.size());
94 memset(const_cast<char*>(exportPassword.c_str()), 0, exportPassword.size());
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070095
96 if (output == "-")
Alexander Afanasyev35109a12017-01-04 15:39:06 -080097 io::save(*safeBag, std::cout);
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070098 else
Alexander Afanasyev35109a12017-01-04 15:39:06 -080099 io::save(*safeBag, output);
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700100
101 return 0;
102 }
Alexander Afanasyev35109a12017-01-04 15:39:06 -0800103 catch (const std::runtime_error& e) {
104 std::cerr << "ERROR: " << e.what() << std::endl;
105 memset(const_cast<char*>(exportPassword.c_str()), 0, exportPassword.size());
106 return 1;
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700107 }
Yingdi Yu8d7468f2014-02-21 14:49:45 -0800108}
109
Alexander Afanasyev82c359c2017-01-04 14:48:07 -0800110} // namespace ndnsec
111} // namespace ndn